Re: [CMake] SuperBuild whoes
On 04/26/2011 03:19 PM, Michael Wild wrote: On 04/26/2011 02:48 PM, Michael Hertling wrote: On 04/25/2011 05:15 PM, Michael Wild wrote: On 04/25/2011 04:51 PM, Michael Hertling wrote: [...] [...] The only thing that required some thinking was writing a relocatable XXXConfig.cmake file. I think I will update my tutorial on the WIKI to use a un-configured, relocatable XXXConfig.cmake file. Just a hint for that tutorial, though off-topic: Targets may usually not be defined multiple times, i.e. the export file generated by INSTALL(EXPORT ...) may not be included more than once, so the include(@FOOBAR_CMAKE_DIR@/FooBarLibraryDepends.cmake) should possibly be guarded by IF(NOT TARGET ...)/ENDIF() constructs. Otherwise, the resulting FooBarConfig.cmake file must not be loaded twice or more - unless one is aware of the imported targets' feature of being, say, half-scoped, cf. [1]. This might be an uncomfortable limitation, in particular w.r.t. multi-component packages. Regrettably, such IF(NOT TARGET ...)/ENDIF() constructs can hardly be automated, so one could perhaps consider to allow redefinitions for imported targets. Due to the absence of sources, this should be much easier to implement than for non-imported targets. Good point. I will do something like this: get_property(FOOBAR_INCLUDED GLOBAL PROPERTY FOOBAR_INCLUDED DEFINED) if(NOT FOOBAR_INCLUDED) # include FooBarLibraryDepends.cmake here set_property(GLOBAL PROPERTY FOOBAR_INCLUDED TRUE) endif() Don't do it in this way. First, the DEFINED clause of GET_PROPERTY() queries if the property has been *defined* by DEFINE_PROPERTY(); if it is *set* by SET_PROPERTY() et al. doesn't matter in this regard. See the following CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(PROPERTIES NONE) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P initially: defined=${d}, set=${s}) SET_PROPERTY(GLOBAL PROPERTY P TRUE) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P after setting: defined=${d}, set=${s}) DEFINE_PROPERTY(GLOBAL PROPERTY P BRIEF_DOCS P FULL_DOCS P) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P after defining: defined=${d}, set=${s}) Thus, you must use GET_PROPERTY()'s SET clause to achieve your aim. Argh, sorry. I meant SET, of course. Moreover, imported targets - in contrast to traditional ones - are, as I said, half-scoped, i.e. they've a scope like variables, but cannot be overwritten/redefined. As a consequence, you can define an imported target in a subdirectory, and subsequently, i.e. after returning from ADD_SUBDIRECTORY(), you can define it again the current scope. If you guard an export file's inclusion by a global property, the inclusion will fail if it has taken place earlier in a subdirectory, so the imported targets will be undefined in the current scope. See the following CMakeLists.txt files: # CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(FOOBAR NONE) ADD_SUBDIRECTORY(subdir) GET_PROPERTY(FOOBAR_DEFINED GLOBAL PROPERTY FOOBAR_DEFINED SET) IF(NOT FOOBAR_DEFINED) ADD_EXECUTABLE(foobar IMPORTED) SET_PROPERTY(GLOBAL PROPERTY FOOBAR_DEFINED TRUE) ENDIF() IF(TARGET foobar) MESSAGE(Target foobar defined at toplevel) ELSE() MESSAGE(Target foobar NOT defined at toplevel) ENDIF() # subdir/CMakeLists.txt: GET_PROPERTY(FOOBAR_DEFINED GLOBAL PROPERTY FOOBAR_DEFINED SET) IF(NOT FOOBAR_DEFINED) ADD_EXECUTABLE(foobar IMPORTED) SET_PROPERTY(GLOBAL PROPERTY FOOBAR_DEFINED TRUE) ENDIF() IF(TARGET foobar) MESSAGE(Target foobar defined in subdir) ELSE() MESSAGE(Target foobar NOT defined in subdir) ENDIF() Instead, you should use either directory properties to protect imported targets from being redefined - appropriate to their scoping - or just ordinary variables, though none of these solutions is bullet-proof. This is truly infuriating... Inherited directory properties seem to be the way to go then... The reason I like to use properties is that they are much less used than variables, reducing the potential for naming conflicts. Alternatively, one might consider to provide a function specifically designed for the accident-free inclusion of export files, e.g. like: FUNCTION(INCLUDE_EXPORT EXPORTFILE) SET(TARGETSDEFINED FALSE) FOREACH(i IN LISTS ARGN) IF(TARGET ${i}) SET(TARGETSDEFINED TRUE) ENDIF() ENDFOREACH() IF(NOT TARGETSDEFINED) INCLUDE(${EXPORTFILE}) ENDIF() ENDFUNCTION() Apparently, a function's scope does not shield an imported target from the surrounding scope as a directory's scope does. However, one needs to provide the targets when invoking INCLUDE_EXPORT(), but probably it's quite possible to retrieve them automatically by scanning the export file, e.g. with an ADD_.+\(([^ ]+)IMPORTED\) or the like. Nah, too roundabout... IMO, the interdiction of -
Re: [CMake] SuperBuild whoes
On 04/25/2011 05:15 PM, Michael Wild wrote: On 04/25/2011 04:51 PM, Michael Hertling wrote: [...] I also solved my installation problem. By having all sub-projects install into a common prefix, and thanks to the wonders of RPATH and install_name which can handle relative paths and thanks to the fact that install(EXPORT) generated files are also relocatable, I can simply do a install(DIRECTORY) in the super project ;-) [...] Does this mean you've the subprojects configured for installation with a prefix of, say, ${CMAKE_BINARY_DIR}/externals and the superproject's CMAKE_BINARY_DIR, and add INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/externals DESTINATION ${CMAKE_INSTALL_PREFIX}) to the superproject's top-level CMakeLists.txt in order to relocate the subprojects to the actual installation directory in the end? If so, how do you cope with subprojects which incorporate paths derived from their installation prefix as hard-coded defaults, e.g. prefix/etc - or /etc if prefix equals /usr - for the package's configurational data? Following your approach, if I'm not mistaken, the subprojects would end up with ${CMAKE_BINARY_DIR}/externals/etc and CMAKE_BINARY_DIR pointing to the superproject's build tree. Of course, this might result in certain failures, or do I completely misunderstand your afore-noted outline? That's true, but all the sub-projects are under my control, so I can take care of it. To be more robust, one could possibly configure the subprojects with the final installation prefix, i.e. the superproject's CMAKE_INSTALL_PREFIX, and use a DESTDIR of ${CMAKE_BINARY_DIR}/externals in the installation command to perform the intermediate installation in the build tree. Finally, an INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/externals/${CMAKE_INSTALL_PREFIX}/ DESTINATION ${CMAKE_INSTALL_PREFIX}) would relocate the subprojects to their designated - and configured - installation directory. Admittedly, this approach's shortcomings are: - On Windows, it would need further ado because of the drive letters. - Not all (sub)projects support a DESTDIR feature for installation; at least, CMake-based projects do, and autotooled ones do it, too, AFAIK. - If the subprojects don't provide flexible alternatives for hard coded paths, e.g. environment variables or command line options, they might fail to run from within the superproject's build tree, but at least, their headers can be used to compile and the libraries to resolve symbols, and FIND_PACKAGE() will be happy when it's instructed: CMAKE_PREFIX_PATH=${CMAKE_BINARY_DIR}/externals/${CMAKE_INSTALL_PREFIX} At worst, i.e. with subprojects that actually rely on hard coded paths and need to be run from within the build tree, it's probably necessary to build these projects twice: Once for the intermediate installation and another time for the final one. Relocation remains critical... ;) [...] The only thing that required some thinking was writing a relocatable XXXConfig.cmake file. I think I will update my tutorial on the WIKI to use a un-configured, relocatable XXXConfig.cmake file. Just a hint for that tutorial, though off-topic: Targets may usually not be defined multiple times, i.e. the export file generated by INSTALL(EXPORT ...) may not be included more than once, so the include(@FOOBAR_CMAKE_DIR@/FooBarLibraryDepends.cmake) should possibly be guarded by IF(NOT TARGET ...)/ENDIF() constructs. Otherwise, the resulting FooBarConfig.cmake file must not be loaded twice or more - unless one is aware of the imported targets' feature of being, say, half-scoped, cf. [1]. This might be an uncomfortable limitation, in particular w.r.t. multi-component packages. Regrettably, such IF(NOT TARGET ...)/ENDIF() constructs can hardly be automated, so one could perhaps consider to allow redefinitions for imported targets. Due to the absence of sources, this should be much easier to implement than for non-imported targets. Good point. I will do something like this: get_property(FOOBAR_INCLUDED GLOBAL PROPERTY FOOBAR_INCLUDED DEFINED) if(NOT FOOBAR_INCLUDED) # include FooBarLibraryDepends.cmake here set_property(GLOBAL PROPERTY FOOBAR_INCLUDED TRUE) endif() Don't do it in this way. First, the DEFINED clause of GET_PROPERTY() queries if the property has been *defined* by DEFINE_PROPERTY(); if it is *set* by SET_PROPERTY() et al. doesn't matter in this regard. See the following CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(PROPERTIES NONE) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P initially: defined=${d}, set=${s}) SET_PROPERTY(GLOBAL PROPERTY P TRUE) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P after setting: defined=${d}, set=${s}) DEFINE_PROPERTY(GLOBAL PROPERTY P BRIEF_DOCS P FULL_DOCS P) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P after
Re: [CMake] SuperBuild whoes
On 04/26/2011 02:48 PM, Michael Hertling wrote: On 04/25/2011 05:15 PM, Michael Wild wrote: On 04/25/2011 04:51 PM, Michael Hertling wrote: [...] [...] The only thing that required some thinking was writing a relocatable XXXConfig.cmake file. I think I will update my tutorial on the WIKI to use a un-configured, relocatable XXXConfig.cmake file. Just a hint for that tutorial, though off-topic: Targets may usually not be defined multiple times, i.e. the export file generated by INSTALL(EXPORT ...) may not be included more than once, so the include(@FOOBAR_CMAKE_DIR@/FooBarLibraryDepends.cmake) should possibly be guarded by IF(NOT TARGET ...)/ENDIF() constructs. Otherwise, the resulting FooBarConfig.cmake file must not be loaded twice or more - unless one is aware of the imported targets' feature of being, say, half-scoped, cf. [1]. This might be an uncomfortable limitation, in particular w.r.t. multi-component packages. Regrettably, such IF(NOT TARGET ...)/ENDIF() constructs can hardly be automated, so one could perhaps consider to allow redefinitions for imported targets. Due to the absence of sources, this should be much easier to implement than for non-imported targets. Good point. I will do something like this: get_property(FOOBAR_INCLUDED GLOBAL PROPERTY FOOBAR_INCLUDED DEFINED) if(NOT FOOBAR_INCLUDED) # include FooBarLibraryDepends.cmake here set_property(GLOBAL PROPERTY FOOBAR_INCLUDED TRUE) endif() Don't do it in this way. First, the DEFINED clause of GET_PROPERTY() queries if the property has been *defined* by DEFINE_PROPERTY(); if it is *set* by SET_PROPERTY() et al. doesn't matter in this regard. See the following CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(PROPERTIES NONE) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P initially: defined=${d}, set=${s}) SET_PROPERTY(GLOBAL PROPERTY P TRUE) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P after setting: defined=${d}, set=${s}) DEFINE_PROPERTY(GLOBAL PROPERTY P BRIEF_DOCS P FULL_DOCS P) GET_PROPERTY(d GLOBAL PROPERTY P DEFINED) GET_PROPERTY(s GLOBAL PROPERTY P SET) MESSAGE(P after defining: defined=${d}, set=${s}) Thus, you must use GET_PROPERTY()'s SET clause to achieve your aim. Argh, sorry. I meant SET, of course. Moreover, imported targets - in contrast to traditional ones - are, as I said, half-scoped, i.e. they've a scope like variables, but cannot be overwritten/redefined. As a consequence, you can define an imported target in a subdirectory, and subsequently, i.e. after returning from ADD_SUBDIRECTORY(), you can define it again the current scope. If you guard an export file's inclusion by a global property, the inclusion will fail if it has taken place earlier in a subdirectory, so the imported targets will be undefined in the current scope. See the following CMakeLists.txt files: # CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(FOOBAR NONE) ADD_SUBDIRECTORY(subdir) GET_PROPERTY(FOOBAR_DEFINED GLOBAL PROPERTY FOOBAR_DEFINED SET) IF(NOT FOOBAR_DEFINED) ADD_EXECUTABLE(foobar IMPORTED) SET_PROPERTY(GLOBAL PROPERTY FOOBAR_DEFINED TRUE) ENDIF() IF(TARGET foobar) MESSAGE(Target foobar defined at toplevel) ELSE() MESSAGE(Target foobar NOT defined at toplevel) ENDIF() # subdir/CMakeLists.txt: GET_PROPERTY(FOOBAR_DEFINED GLOBAL PROPERTY FOOBAR_DEFINED SET) IF(NOT FOOBAR_DEFINED) ADD_EXECUTABLE(foobar IMPORTED) SET_PROPERTY(GLOBAL PROPERTY FOOBAR_DEFINED TRUE) ENDIF() IF(TARGET foobar) MESSAGE(Target foobar defined in subdir) ELSE() MESSAGE(Target foobar NOT defined in subdir) ENDIF() Instead, you should use either directory properties to protect imported targets from being redefined - appropriate to their scoping - or just ordinary variables, though none of these solutions is bullet-proof. This is truly infuriating... Inherited directory properties seem to be the way to go then... The reason I like to use properties is that they are much less used than variables, reducing the potential for naming conflicts. Alternatively, one might consider to provide a function specifically designed for the accident-free inclusion of export files, e.g. like: FUNCTION(INCLUDE_EXPORT EXPORTFILE) SET(TARGETSDEFINED FALSE) FOREACH(i IN LISTS ARGN) IF(TARGET ${i}) SET(TARGETSDEFINED TRUE) ENDIF() ENDFOREACH() IF(NOT TARGETSDEFINED) INCLUDE(${EXPORTFILE}) ENDIF() ENDFUNCTION() Apparently, a function's scope does not shield an imported target from the surrounding scope as a directory's scope does. However, one needs to provide the targets when invoking INCLUDE_EXPORT(), but probably it's quite possible to retrieve them automatically by scanning the export file, e.g. with an ADD_.+\(([^ ]+)IMPORTED\) or the like. Nah, too roundabout... IMO, the interdiction of - equivalently - redefining imported targets
Re: [CMake] SuperBuild whoes
On 04/21/2011 03:44 PM, Michael Wild wrote: On 04/21/2011 02:45 PM, David Cole wrote: On Thu, Apr 21, 2011 at 4:30 AM, Michael Wild them...@gmail.com mailto:them...@gmail.com wrote: On 04/21/2011 06:48 AM, Michael Wild wrote: Hi all I'm trying to set up a SuperBuild here. Everything works nicely the first time round I build the project. The only real problem I have is that if I change the sources of one of the sub-projects, the SuperBuild still thinks everything is up to date. Of course, this is fully explainable by the fact that the SuperBuild knows nothing about the internal dependencies of the sub-project, and since the stamp files are all there and unchanged, it thinks everything is fine. How do I get around this? Anybody got an idea? Thanks Michael Found it myself. For completeness and documentation purposes: Add a custom target which removes the *-complete (see ExternalProject.cmake on where it is located, it is a bit tricky) and -*configure stamps. Of course, it should always run and depend on the external project target. The thing I'm struggling with now is installing the various sub-projects into the system. Seems like it is impossible to install an imported target [1], but guessing and hard coding the paths is also not very attractive, but probably the only way to go at the moment. If anybody has a better idea, please speak up... Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg18336.html ___ Powered by www.kitware.com http://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 If your intent is *always* to run the configure and later steps of an ExternalProject build, you can consider adding an extra custom step that configure depends on, which does nothing, but ALWAYS runs... No need to do any fancy scrounging of stamp files for this to work. Something like: ExternalProject_Add(Proj1 ... ) ExternalProject_Add_Step(Proj1 forceconfigure COMMAND ${CMAKE_COMMAND} -E echo This custom external project step forces the configure and later steps to run whenever a top level build is done... DEPENDEES download DEPENDERS configure ALWAYS 1 ) By the way, this is how repository-based checkouts always build. A cvs, git or svn checkout's update step *always* runs (by default, unless you override UPDATE_COMMAND), and since the configure step depends on the update step, they also always configure, build and install. HTH, David Mhm, I thought I already tried this, but will check again. Thanks for the input. I also solved my installation problem. By having all sub-projects install into a common prefix, and thanks to the wonders of RPATH and install_name which can handle relative paths and thanks to the fact that install(EXPORT) generated files are also relocatable, I can simply do a install(DIRECTORY) in the super project ;-) [...] Does this mean you've the subprojects configured for installation with a prefix of, say, ${CMAKE_BINARY_DIR}/externals and the superproject's CMAKE_BINARY_DIR, and add INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/externals DESTINATION ${CMAKE_INSTALL_PREFIX}) to the superproject's top-level CMakeLists.txt in order to relocate the subprojects to the actual installation directory in the end? If so, how do you cope with subprojects which incorporate paths derived from their installation prefix as hard-coded defaults, e.g. prefix/etc - or /etc if prefix equals /usr - for the package's configurational data? Following your approach, if I'm not mistaken, the subprojects would end up with ${CMAKE_BINARY_DIR}/externals/etc and CMAKE_BINARY_DIR pointing to the superproject's build tree. Of course, this might result in certain failures, or do I completely misunderstand your afore-noted outline? [...] The only thing that required some thinking was writing a relocatable XXXConfig.cmake file. I think I will update my tutorial on the WIKI to use a un-configured, relocatable XXXConfig.cmake file. Just a hint for that tutorial, though off-topic: Targets may usually not be defined multiple times, i.e. the export file generated by INSTALL(EXPORT ...) may not be included more than once, so the include(@FOOBAR_CMAKE_DIR@/FooBarLibraryDepends.cmake) should possibly be guarded by IF(NOT TARGET ...)/ENDIF() constructs. Otherwise, the resulting FooBarConfig.cmake file must not be loaded twice or more - unless one is aware of the imported targets' feature of being, say, half-scoped, cf. [1]. This might be an uncomfortable limitation, in particular
Re: [CMake] SuperBuild whoes
On 04/25/2011 04:51 PM, Michael Hertling wrote: [...] I also solved my installation problem. By having all sub-projects install into a common prefix, and thanks to the wonders of RPATH and install_name which can handle relative paths and thanks to the fact that install(EXPORT) generated files are also relocatable, I can simply do a install(DIRECTORY) in the super project ;-) [...] Does this mean you've the subprojects configured for installation with a prefix of, say, ${CMAKE_BINARY_DIR}/externals and the superproject's CMAKE_BINARY_DIR, and add INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/externals DESTINATION ${CMAKE_INSTALL_PREFIX}) to the superproject's top-level CMakeLists.txt in order to relocate the subprojects to the actual installation directory in the end? If so, how do you cope with subprojects which incorporate paths derived from their installation prefix as hard-coded defaults, e.g. prefix/etc - or /etc if prefix equals /usr - for the package's configurational data? Following your approach, if I'm not mistaken, the subprojects would end up with ${CMAKE_BINARY_DIR}/externals/etc and CMAKE_BINARY_DIR pointing to the superproject's build tree. Of course, this might result in certain failures, or do I completely misunderstand your afore-noted outline? That's true, but all the sub-projects are under my control, so I can take care of it. [...] The only thing that required some thinking was writing a relocatable XXXConfig.cmake file. I think I will update my tutorial on the WIKI to use a un-configured, relocatable XXXConfig.cmake file. Just a hint for that tutorial, though off-topic: Targets may usually not be defined multiple times, i.e. the export file generated by INSTALL(EXPORT ...) may not be included more than once, so the include(@FOOBAR_CMAKE_DIR@/FooBarLibraryDepends.cmake) should possibly be guarded by IF(NOT TARGET ...)/ENDIF() constructs. Otherwise, the resulting FooBarConfig.cmake file must not be loaded twice or more - unless one is aware of the imported targets' feature of being, say, half-scoped, cf. [1]. This might be an uncomfortable limitation, in particular w.r.t. multi-component packages. Regrettably, such IF(NOT TARGET ...)/ENDIF() constructs can hardly be automated, so one could perhaps consider to allow redefinitions for imported targets. Due to the absence of sources, this should be much easier to implement than for non-imported targets. Good point. I will do something like this: get_property(FOOBAR_INCLUDED GLOBAL PROPERTY FOOBAR_INCLUDED DEFINED) if(NOT FOOBAR_INCLUDED) # include FooBarLibraryDepends.cmake here set_property(GLOBAL PROPERTY FOOBAR_INCLUDED TRUE) endif() Regards, Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg29441.html Michael ___ 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
Re: [CMake] SuperBuild whoes
On 04/21/2011 06:48 AM, Michael Wild wrote: Hi all I'm trying to set up a SuperBuild here. Everything works nicely the first time round I build the project. The only real problem I have is that if I change the sources of one of the sub-projects, the SuperBuild still thinks everything is up to date. Of course, this is fully explainable by the fact that the SuperBuild knows nothing about the internal dependencies of the sub-project, and since the stamp files are all there and unchanged, it thinks everything is fine. How do I get around this? Anybody got an idea? Thanks Michael Found it myself. For completeness and documentation purposes: Add a custom target which removes the *-complete (see ExternalProject.cmake on where it is located, it is a bit tricky) and -*configure stamps. Of course, it should always run and depend on the external project target. The thing I'm struggling with now is installing the various sub-projects into the system. Seems like it is impossible to install an imported target [1], but guessing and hard coding the paths is also not very attractive, but probably the only way to go at the moment. If anybody has a better idea, please speak up... Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg18336.html ___ 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
Re: [CMake] SuperBuild whoes
On Thu, Apr 21, 2011 at 4:30 AM, Michael Wild them...@gmail.com wrote: On 04/21/2011 06:48 AM, Michael Wild wrote: Hi all I'm trying to set up a SuperBuild here. Everything works nicely the first time round I build the project. The only real problem I have is that if I change the sources of one of the sub-projects, the SuperBuild still thinks everything is up to date. Of course, this is fully explainable by the fact that the SuperBuild knows nothing about the internal dependencies of the sub-project, and since the stamp files are all there and unchanged, it thinks everything is fine. How do I get around this? Anybody got an idea? Thanks Michael Found it myself. For completeness and documentation purposes: Add a custom target which removes the *-complete (see ExternalProject.cmake on where it is located, it is a bit tricky) and -*configure stamps. Of course, it should always run and depend on the external project target. The thing I'm struggling with now is installing the various sub-projects into the system. Seems like it is impossible to install an imported target [1], but guessing and hard coding the paths is also not very attractive, but probably the only way to go at the moment. If anybody has a better idea, please speak up... Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg18336.html ___ 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 If your intent is *always* to run the configure and later steps of an ExternalProject build, you can consider adding an extra custom step that configure depends on, which does nothing, but ALWAYS runs... No need to do any fancy scrounging of stamp files for this to work. Something like: ExternalProject_Add(Proj1 ... ) ExternalProject_Add_Step(Proj1 forceconfigure COMMAND ${CMAKE_COMMAND} -E echo This custom external project step forces the configure and later steps to run whenever a top level build is done... DEPENDEES download DEPENDERS configure ALWAYS 1 ) By the way, this is how repository-based checkouts always build. A cvs, git or svn checkout's update step *always* runs (by default, unless you override UPDATE_COMMAND), and since the configure step depends on the update step, they also always configure, build and install. HTH, 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
Re: [CMake] SuperBuild whoes
On 04/21/2011 02:45 PM, David Cole wrote: On Thu, Apr 21, 2011 at 4:30 AM, Michael Wild them...@gmail.com mailto:them...@gmail.com wrote: On 04/21/2011 06:48 AM, Michael Wild wrote: Hi all I'm trying to set up a SuperBuild here. Everything works nicely the first time round I build the project. The only real problem I have is that if I change the sources of one of the sub-projects, the SuperBuild still thinks everything is up to date. Of course, this is fully explainable by the fact that the SuperBuild knows nothing about the internal dependencies of the sub-project, and since the stamp files are all there and unchanged, it thinks everything is fine. How do I get around this? Anybody got an idea? Thanks Michael Found it myself. For completeness and documentation purposes: Add a custom target which removes the *-complete (see ExternalProject.cmake on where it is located, it is a bit tricky) and -*configure stamps. Of course, it should always run and depend on the external project target. The thing I'm struggling with now is installing the various sub-projects into the system. Seems like it is impossible to install an imported target [1], but guessing and hard coding the paths is also not very attractive, but probably the only way to go at the moment. If anybody has a better idea, please speak up... Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg18336.html ___ Powered by www.kitware.com http://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 If your intent is *always* to run the configure and later steps of an ExternalProject build, you can consider adding an extra custom step that configure depends on, which does nothing, but ALWAYS runs... No need to do any fancy scrounging of stamp files for this to work. Something like: ExternalProject_Add(Proj1 ... ) ExternalProject_Add_Step(Proj1 forceconfigure COMMAND ${CMAKE_COMMAND} -E echo This custom external project step forces the configure and later steps to run whenever a top level build is done... DEPENDEES download DEPENDERS configure ALWAYS 1 ) By the way, this is how repository-based checkouts always build. A cvs, git or svn checkout's update step *always* runs (by default, unless you override UPDATE_COMMAND), and since the configure step depends on the update step, they also always configure, build and install. HTH, David Mhm, I thought I already tried this, but will check again. Thanks for the input. I also solved my installation problem. By having all sub-projects install into a common prefix, and thanks to the wonders of RPATH and install_name which can handle relative paths and thanks to the fact that install(EXPORT) generated files are also relocatable, I can simply do a install(DIRECTORY) in the super project ;-) The only thing that required some thinking was writing a relocatable XXXConfig.cmake file. I think I will update my tutorial on the WIKI to use a un-configured, relocatable XXXConfig.cmake file. Michael ___ 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