Re: [CMake] Can imported libraries depend on ExternalProject targets?
If I understand what's going on in that bug report, yes add_dependency(imported_library EP_target) should work. But I found that in fact it did not. So maybe that is a bug; if this was fixed in 2.8.4, I don't understand why I still have a problem. On Tue, Jun 26, 2012 at 11:12 AM, Alexander Neundorf wrote: > On Tuesday 26 June 2012, Kent Williams wrote: > >> I meant to say 'the approach you use doesn't work, because imported > >> libraries are targets to are targets to which you CANNOT add > >> dependencies." > > This should work since I think cmake 2.8.4. > > http://public.kitware.com/Bug/view.php?id=10395 > > Or am I misunderstanding what you said ? > > Alex -- 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] Can imported libraries depend on ExternalProject targets?
On Tuesday 26 June 2012, Kent Williams wrote: > I meant to say 'the approach you use doesn't work, because imported > libraries are targets to are targets to which you CANNOT add > dependencies." This should work since I think cmake 2.8.4. http://public.kitware.com/Bug/view.php?id=10395 Or am I misunderstanding what you said ? Alex -- 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] Can imported libraries depend on ExternalProject targets?
I meant to say 'the approach you use doesn't work, because imported libraries are targets to are targets to which you CANNOT add dependencies." On Tue, Jun 26, 2012 at 9:33 AM, Kent Williams wrote: > That seems like it should work, but it actually does not. > > There's two types of precedence in CMake. > > 1. Textual -- as CMake munches through a project and its subdirectory, > it generates a build system where the build order is the same as the > textual order. In a single process build, for example: > > project(x) > add_library(xlib ...) > add_executable(xexec ...) > > 'xlib' will get built before 'xexec' > > 2. The dependency graph. Targets which do not depend on any other > target get built first, then targets that depend on the 'leaf' > targets. In the example above, adding > > target_link_libraries(xexec xlib) > > will make 'xexec' depend on 'xlib', and even if you build using more > than one process (i.e. make -j 8), xexec will be built after xlib. > > I've verified that the approach you use below doesn't work, because > imported libraries are targets to which you can add dependencies. I > tried this approach and it didn't work -- in fact that is what my > original e-mail is about. > > David Cole indicated in essence, I was doing it wrong. My position is > that it's the only way to do it without completely revamping the ITK > build system, which is above my pay grade. > > I thought of a sneaky workaround: Create a dummy library, with one > object file that does nothing, and will never actually be loaded. > Make the dummy library depend on the ExternalProject target, and add > it to library list along with the ExternalProject's libraries. > > But that seems kind of ugly, creating a library no program actually needs. > > On Sat, Jun 23, 2012 at 9:06 AM, Stefan Reuschl > wrote: >> >> The following once worked fine for me using CMake 2.8.8: >> >> ExternalProject_Add( ep ) >> add_library( epLib IMPORTED ) >> set_target_properties( epLib PROPERTIES IMPORTED_LOCATION ... ) >> add_dependencies( epLib ep ) >> -- 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] Can imported libraries depend on ExternalProject targets?
That seems like it should work, but it actually does not. There's two types of precedence in CMake. 1. Textual -- as CMake munches through a project and its subdirectory, it generates a build system where the build order is the same as the textual order. In a single process build, for example: project(x) add_library(xlib ...) add_executable(xexec ...) 'xlib' will get built before 'xexec' 2. The dependency graph. Targets which do not depend on any other target get built first, then targets that depend on the 'leaf' targets. In the example above, adding target_link_libraries(xexec xlib) will make 'xexec' depend on 'xlib', and even if you build using more than one process (i.e. make -j 8), xexec will be built after xlib. I've verified that the approach you use below doesn't work, because imported libraries are targets to which you can add dependencies. I tried this approach and it didn't work -- in fact that is what my original e-mail is about. David Cole indicated in essence, I was doing it wrong. My position is that it's the only way to do it without completely revamping the ITK build system, which is above my pay grade. I thought of a sneaky workaround: Create a dummy library, with one object file that does nothing, and will never actually be loaded. Make the dummy library depend on the ExternalProject target, and add it to library list along with the ExternalProject's libraries. But that seems kind of ugly, creating a library no program actually needs. On Sat, Jun 23, 2012 at 9:06 AM, Stefan Reuschl wrote: > > The following once worked fine for me using CMake 2.8.8: > > ExternalProject_Add( ep ) > add_library( epLib IMPORTED ) > set_target_properties( epLib PROPERTIES IMPORTED_LOCATION ... ) > add_dependencies( epLib ep ) > -- 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] Can imported libraries depend on ExternalProject targets?
On Saturday 23 June 2012, Stefan Reuschl wrote: > Am 22.06.2012, 20:21 Uhr, schrieb Kent Williams > > : > > OK, I guess. > > > > The only reason I bring this up is ITK. If you're familiar with the > > ITK build process, it has a 'module' concept -- not a module in the > > CMake sense (where it is a library intended for runtime loading), but > > in the sense that the build process is modular. Each of the ITK > > libraries is a module, which is defined by a standardised directory > > layout and cmake files. > > > > I made an Module for DCMTK that satisfies the requirements of an ITK > > module -- it builds DCMTK as an External Project, and uses > > add_library(name IMPORTED) on each of the libraries DCMTK > > creates, and connects the imported library with the actual library > > file in the file system. > > > > This all works fine EXCEPT for this one conundrum, you can't have the > > imported libraries depend on the ExternalProject target, so if you > > want to make sure the ExternalProject gets built before the targets > > that try to link to them, you have to make the executable (or library) > > target depend on the ExternalProject target to serialize the build of > > the dependee before the depnder. > > The following once worked fine for me using CMake 2.8.8: > > ExternalProject_Add( ep ) > add_library( epLib IMPORTED ) > set_target_properties( epLib PROPERTIES IMPORTED_LOCATION ... ) > add_dependencies( epLib ep ) Yes, that's what I use too, and it works fine for me, at least if you know what you are doing. Alex -- 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] Can imported libraries depend on ExternalProject targets?
Am 22.06.2012, 20:21 Uhr, schrieb Kent Williams : OK, I guess. The only reason I bring this up is ITK. If you're familiar with the ITK build process, it has a 'module' concept -- not a module in the CMake sense (where it is a library intended for runtime loading), but in the sense that the build process is modular. Each of the ITK libraries is a module, which is defined by a standardised directory layout and cmake files. I made an Module for DCMTK that satisfies the requirements of an ITK module -- it builds DCMTK as an External Project, and uses add_library(name IMPORTED) on each of the libraries DCMTK creates, and connects the imported library with the actual library file in the file system. This all works fine EXCEPT for this one conundrum, you can't have the imported libraries depend on the ExternalProject target, so if you want to make sure the ExternalProject gets built before the targets that try to link to them, you have to make the executable (or library) target depend on the ExternalProject target to serialize the build of the dependee before the depnder. The following once worked fine for me using CMake 2.8.8: ExternalProject_Add( ep ) add_library( epLib IMPORTED ) set_target_properties( epLib PROPERTIES IMPORTED_LOCATION ... ) add_dependencies( epLib ep ) So really it would be easy to just say 'too bad, make ITK its own external project, and build the prerequisite' or 'too bad, add the 3rd party library source to ITK/Modules/ThirdParty the way we've always done it," but it would be kind of awesome if CMake could handle imported libraries depending on targets. No matter if this works, I would like to suggest another approach, which I recently tested for the same use case and which might be helpful: The next problem of using ExternalProject this way is, that the user of the external project need to know the location of public headers and libraries... The CMake way of exporting targets using projectConfig.cmake files won't work because the externals project's config file will be created at build time of the main project - while it is needed at configure time. A workaround without superbuild which David suggested, is to download/ configure/build/install the external project at configure time of the main project. After that, your main project can use find_package(ep). This approach seems to work fine for me. A downside might be, that the main project's configure step will take very long. If the external project supports exporting targets from the build tree, only the download and configure steps need to be executed at configuration time, see: http://www.cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets#Exporting_from_a_Build_Tree If you're curious about what I've done: http://review.source.kitware.com/#/c/5989/ On Fri, Jun 22, 2012 at 12:29 PM, David Cole wrote: On Fri, Jun 22, 2012 at 11:33 AM, Kent Williams wrote: Say I have an ExternalProject that generates several libraries ExternalProject_Add(foo # the usual mumbo jumbo ) set(foo_LIBRARIES) # foo makes 3 libraries foreach(lib a b c) # import the libraries add_library(${lib} STATIC IMPORTED) # tell CMake where the library file is set_property(TARGET ${lib} PROPERTY IMPORTED_LOCATION ${imported_library_filename}) # add to the library list list(APPEND foo_LIBRARIES ${lib}) # this doesn't work apparently add_dependencies(${lib} foo) endforeach() In order for parallel make to work, the foo ExternalProject must complete successfully before any programs that link to ${foo_LIBRARIES} are compiled and linked. I thought that making the imported library targets depend on the ExternalProject target would behave in a transitive manner - i.e. add_executable(foo_user foo.cxx) target_link_libraries(foo_user ${foo_LIBRARIES}) But this is not the case. In a parallel build, the foo_user build doesn't wait for the foo ExternalProject to finish. If I add add_dependencies(foo_user foo) Everything behaves fine. But that requires explicitly add a dependency on an ExternalProject target everywhere it's outputs are used. Is this a bug? A feature request? Or is there another way to make this work? It's neither a bug nor a feature request, it's just the way it works. The explicit dependency is the only way to connect up the outputs of one ExternalProject call to another, which by their nature are independent of one another unless explicitly connected via arguments / cache entries. If you want foo_user to depend on the actual libraries, then it should be its own project that does a find_package(foo) to get them. And then *also* have a SuperBuild that builds foo and then foo_user, where foo_user as an ExternalProject depends on foo as an ExternalProject. The best way to use ExternalProject is to have a SuperBuild project that builds *everything* as an ExternalProject. It's not easy (or advisable, in my thinking) to combine ExternalProject calls with non-ExternalProject CMake ta
Re: [CMake] Can imported libraries depend on ExternalProject targets?
OK, I guess. The only reason I bring this up is ITK. If you're familiar with the ITK build process, it has a 'module' concept -- not a module in the CMake sense (where it is a library intended for runtime loading), but in the sense that the build process is modular. Each of the ITK libraries is a module, which is defined by a standardised directory layout and cmake files. I made an Module for DCMTK that satisfies the requirements of an ITK module -- it builds DCMTK as an External Project, and uses add_library(name IMPORTED) on each of the libraries DCMTK creates, and connects the imported library with the actual library file in the file system. This all works fine EXCEPT for this one conundrum, you can't have the imported libraries depend on the ExternalProject target, so if you want to make sure the ExternalProject gets built before the targets that try to link to them, you have to make the executable (or library) target depend on the ExternalProject target to serialize the build of the dependee before the depnder. So really it would be easy to just say 'too bad, make ITK its own external project, and build the prerequisite' or 'too bad, add the 3rd party library source to ITK/Modules/ThirdParty the way we've always done it," but it would be kind of awesome if CMake could handle imported libraries depending on targets. If you're curious about what I've done: http://review.source.kitware.com/#/c/5989/ On Fri, Jun 22, 2012 at 12:29 PM, David Cole wrote: > On Fri, Jun 22, 2012 at 11:33 AM, Kent Williams > wrote: >> >> Say I have an ExternalProject that generates several libraries >> >> ExternalProject_Add(foo >> # the usual mumbo jumbo >> ) >> >> set(foo_LIBRARIES) >> >> # foo makes 3 libraries >> foreach(lib a b c) >> # import the libraries >> add_library(${lib} STATIC IMPORTED) >> >> # tell CMake where the library file is >> set_property(TARGET ${lib} PROPERTY >> IMPORTED_LOCATION >> ${imported_library_filename}) >> >> # add to the library list >> list(APPEND foo_LIBRARIES ${lib}) >> >> # this doesn't work apparently >> add_dependencies(${lib} foo) >> endforeach() >> >> In order for parallel make to work, the foo ExternalProject must >> complete successfully before any programs that link to >> ${foo_LIBRARIES} are compiled and linked. >> >> I thought that making the imported library targets depend on the >> ExternalProject target would behave in a transitive manner - i.e. >> >> add_executable(foo_user foo.cxx) >> target_link_libraries(foo_user ${foo_LIBRARIES}) >> >> But this is not the case. In a parallel build, the foo_user build >> doesn't wait for the foo ExternalProject to finish. >> >> If I add >> >> add_dependencies(foo_user foo) >> >> Everything behaves fine. But that requires explicitly add a >> dependency on an ExternalProject target everywhere it's outputs are >> used. >> >> Is this a bug? A feature request? Or is there another way to make this >> work? > > > > It's neither a bug nor a feature request, it's just the way it works. The > explicit dependency is the only way to connect up the outputs of one > ExternalProject call to another, which by their nature are independent of > one another unless explicitly connected via arguments / cache entries. > > If you want foo_user to depend on the actual libraries, then it should be > its own project that does a find_package(foo) to get them. And then *also* > have a SuperBuild that builds foo and then foo_user, where foo_user as an > ExternalProject depends on foo as an ExternalProject. > > The best way to use ExternalProject is to have a SuperBuild project that > builds *everything* as an ExternalProject. > > It's not easy (or advisable, in my thinking) to combine ExternalProject > calls with non-ExternalProject CMake targets. That's why I recommend a > SuperBuild, with exclusively ExternalProject targets, as the best bet. > > > 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 > > -- 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] Can imported libraries depend on ExternalProject targets?
On Fri, Jun 22, 2012 at 11:33 AM, Kent Williams wrote: > Say I have an ExternalProject that generates several libraries > > ExternalProject_Add(foo > # the usual mumbo jumbo > ) > > set(foo_LIBRARIES) > > # foo makes 3 libraries > foreach(lib a b c) > # import the libraries > add_library(${lib} STATIC IMPORTED) > > # tell CMake where the library file is > set_property(TARGET ${lib} PROPERTY > IMPORTED_LOCATION > ${imported_library_filename}) > > # add to the library list > list(APPEND foo_LIBRARIES ${lib}) > > # this doesn't work apparently > add_dependencies(${lib} foo) > endforeach() > > In order for parallel make to work, the foo ExternalProject must > complete successfully before any programs that link to > ${foo_LIBRARIES} are compiled and linked. > > I thought that making the imported library targets depend on the > ExternalProject target would behave in a transitive manner - i.e. > > add_executable(foo_user foo.cxx) > target_link_libraries(foo_user ${foo_LIBRARIES}) > > But this is not the case. In a parallel build, the foo_user build > doesn't wait for the foo ExternalProject to finish. > > If I add > > add_dependencies(foo_user foo) > > Everything behaves fine. But that requires explicitly add a > dependency on an ExternalProject target everywhere it's outputs are > used. > > Is this a bug? A feature request? Or is there another way to make this > work? > It's neither a bug nor a feature request, it's just the way it works. The explicit dependency is the only way to connect up the outputs of one ExternalProject call to another, which by their nature are independent of one another unless explicitly connected via arguments / cache entries. If you want foo_user to depend on the actual libraries, then it should be its own project that does a find_package(foo) to get them. And then *also* have a SuperBuild that builds foo and then foo_user, where foo_user as an ExternalProject depends on foo as an ExternalProject. The best way to use ExternalProject is to have a SuperBuild project that builds *everything* as an ExternalProject. It's not easy (or advisable, in my thinking) to combine ExternalProject calls with non-ExternalProject CMake targets. That's why I recommend a SuperBuild, with exclusively ExternalProject targets, as the best bet. 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 > -- 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