<div class="gmail_extra"><div class="gmail_quote">On Fri, Dec 7, 2012 at 2:20 PM, Bill Katz <span dir="ltr"><<a href="mailto:billkatz@gmail.com" target="_blank">billkatz@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Hi,<div><br></div><div>I love the ExternalProject_Add module and use it extensively in an open-source build system I'm developing for our apps:</div><div><br></div><div><a href="https://github.com/janelia-flyem/buildem" target="_blank">http://github.com/janelia-flyem/buildem</a></div>
<div><br></div><div>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.</div>
<div><br></div></blockquote><div><br></div><div>Why not just one command? ;-)</div><div> ( See item 2 of the 12-item Joel Test: <a href="http://www.joelonsoftware.com/articles/fog0000000043.html">http://www.joelonsoftware.com/articles/fog0000000043.html</a> )</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div></div><div>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.</div>
</blockquote><div><br></div><div>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.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><br></div><div>So I was hoping to get clarification on the different ways of specifying dependencies and what happens after those statements.</div><div><br></div><div>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.</div>
<div><br></div></blockquote><div><br></div><div>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.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div></div><div>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?</div>
<div><br></div></blockquote><div><br></div><div>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?)</div><div><br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div></div><div>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:</div>
<div><br></div><div>project(EP1)</div><div><br></div><div>add_library(EP1 ${SOURCES})</div><div>add_dependencies(EP1 ep3 ep4)</div><div><br></div><div>add_custom_command(TARGET EP1</div><div> DEPENDS EP2 EP3</div>
<div> COMMAND dostuff)</div><div><br></div><div>add_custom_command(OUTPUT some_constants.h ${more_autogen_include_files}</div><div> DEPENDS thrift_EP</div><div> COMMAND generate_includes)</div>
<div><br></div><div>add_executable(foo foo.cpp)</div><div>target_link_libraries(foo EP1 ${foolibs})</div><div><br></div><div>set_source_files_properties(somestuff.cpp </div><div> PROPERTIES OBJECT_DEPENDS ${generated_file_dir}/some_constants.h)</div>
<div><br></div><div><br></div><div>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.</div><div>
<br></div><div>Thanks,</div><div>Bill</div>
<br></blockquote><div><br></div><div>Be careful with your target names and add_dependencies. Be aware of this bug: <a href="http://public.kitware.com/Bug/view.php?id=9188">http://public.kitware.com/Bug/view.php?id=9188</a> -- 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?</div>
<div><br></div><div>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.</div>
<div><br></div><div>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.</div><div><br></div><div><br></div><div>Hope this helps figure something out for you....</div>
<div><br></div><div>David<br></div><div><br></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
--<br>
<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" target="_blank">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.cmake.org/mailman/listinfo/cmake" target="_blank">http://www.cmake.org/mailman/listinfo/cmake</a><br></blockquote></div><br></div>