Am 22.06.2012, 20:21 Uhr, schrieb Kent Williams <nkwmailingli...@gmail.com>:

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 <lib-type> 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 <david.c...@kitware.com> wrote:
On Fri, Jun 22, 2012 at 11:33 AM, Kent Williams <nkwmailingli...@gmail.com>
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
--

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

Reply via email to