[CMake] Question on ExternalProject_Add and different dependency directives
David Cole
david.cole at kitware.com
Fri Dec 14 16:45:05 EST 2012
On Fri, Dec 7, 2012 at 2:20 PM, Bill Katz <billkatz at gmail.com> wrote:
> Hi,
>
> I love the ExternalProject_Add module and use it extensively in an
> open-source build system I'm developing for our apps:
>
> http://github.com/janelia-flyem/buildem<https://github.com/janelia-flyem/buildem>
>
> The idea is to make a build environment from source, using cached
> tarballs, and allow different version dependency graphs as commits in a git
> repository of all build modules. I don't use FindPackage because we want
> to know exactly how dependencies are built and modify parameters for some
> of them. Also, just about everything above the language compiler level
> gets built into one build prefix directory. The goal is to run at most two
> "cmake..; make..." commands and have the system completely download and
> build all necessary components from archived source.
>
>
Why not just one command? ;-)
( See item 2 of the 12-item Joel Test:
http://www.joelonsoftware.com/articles/fog0000000043.html )
In looking through the CMake message boards, I think I understand that
> external projects aren't real targets but can still be used as
> dependencies. As long as I use the DEPENDS in ExternalProject_Add(), the
> dependencies seem to work as expected. However, I've run into an issue
> where I'm using add_dependencies(EP1) where EP1 is an external project and
> it's being rebuilt regardless of whether it was built already.
>
It's not that external projects aren't "real" targets. But they are custom
targets that have a chain of associated custom commands based on your
parameters to ExternalProject_Add.
>
> So I was hoping to get clarification on the different ways of specifying
> dependencies and what happens after those statements.
>
> DEPENDS in ExternalProject_Add lets you specify other external project
> targets. The dependencies only get downloaded and built once. Question:
> how does ExternalProject_Add determine when an external project needs to go
> through its stages again? I read that git repo external projects are
> always pulled unless you explicitly use an empty UPDATE_COMMAND.
>
>
The dependencies are strictly time-stamp based. Each step has a stamp file
that it writes out after the step executes successfully. The step should
not rerun, unless a step that it depends on is re-run, or it is marked as
an ALWAYS re-run step... If it does, there's a bug somewhere.
> If two different CMakeLists.txt include the same cmake file with a fixed
> ExternalProject_Add's PREFIX directory, could there be some thrashing going
> on?
>
>
I suppose so, but I don't really understand the question. Could you give an
example? (Perhaps a link to a specific line of code in your github project?)
> add_dependencies(myexe EP1 EP2...) seems to work efficiently for most of
> my modules (i.e, doesn't try to download, configure, etc, if it's done so
> already), but for some more complicated ones, the external projects and its
> dependencies always get rebuilt. I'm assuming there's something in my
> modules that forces rebuilding of an external project even if its built.
> In the suspect CMakeLists.txt for external project EP1 that I own, I have
> a number of commands of the form:
>
> project(EP1)
>
> add_library(EP1 ${SOURCES})
> add_dependencies(EP1 ep3 ep4)
>
> add_custom_command(TARGET EP1
> DEPENDS EP2 EP3
> COMMAND dostuff)
>
> add_custom_command(OUTPUT some_constants.h ${more_autogen_include_files}
> DEPENDS thrift_EP
> COMMAND generate_includes)
>
> add_executable(foo foo.cpp)
> target_link_libraries(foo EP1 ${foolibs})
>
> set_source_files_properties(somestuff.cpp
> PROPERTIES OBJECT_DEPENDS ${generated_file_dir}/some_constants.h)
>
>
> I think there's either a deficiency in my understanding and/or one of the
> above is forcing rebuilds. Any help would be appreciated in figuring out
> where I'm going wrong.
>
> Thanks,
> Bill
>
>
Be careful with your target names and add_dependencies. Be aware of this
bug: http://public.kitware.com/Bug/view.php?id=9188 -- also, I notice you
have both "ep3" and "EP3" -- those are different because the case is
different, but on Windows, if any files are based on target names, the
case-insensitive file system will have you trouncing files if both names
are actually used. Do you actually have such differences, or is that just a
typo in the email?
I always use the OUTPUT form of add_custom_command, and then hook up the
output to a DEPENDS clause of an add_custom_target. Then I specify
inter-target dependencies with add_dependencies. I have not yet had a
problem with this technique, which is used extensively in the
ExternalProject chain of custom commands.
I have not used the add_custom_command(TARGET signature very much. Tracing
what changes are causing build re-runs is not an easy task.
Hope this helps figure something out for you....
David
> --
>
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20121214/74803176/attachment-0001.htm>
More information about the CMake
mailing list