Re: [CMake] Creating relocatable export files

2016-01-07 Thread Alexander Neundorf
On Saturday, November 14, 2015 12:19:11 Nicholas Braden wrote:
> Instead of using FOO_INCLUDE_DIR, I believe you should use
> target_include_directories() with the INTERFACE or PUBLIC options -
> this will export the include directories properly and they will be
> used when someone target_link_library()s your exported target.
> https://cmake.org/cmake/help/latest/command/target_include_directories.html?
> highlight=INTERFACE
> 
> There seems to be a section in the documentation on making sure your
> packages are relocatable:
> https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-re
> locatable-packages
> 
> See also:
> https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html

this is from before the fancy target-include-directories-propagation 
functionality was added, it shouldn't be necessary anymore.

Alex

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake


Re: [CMake] Creating relocatable export files

2015-11-14 Thread Tamás Kenéz
You need to manually write your config module which takes care of the
dependencies. Of course you will still use the generated exports, too.

For now let's say `ome-common` has one dependency: `omedep` and its
config-module, `omedep-config.cmake` creates the imported lib target
`omedep::omedep`. The in `ome-common`'s CMakeLists.txt:

target_link_libraries(ome-common PUBLIC omedep::omedep)
install(TARGETS ome-common
EXPORT ome-common-targets )
install(EXPORT ome-common-targets
DESTINATION cmake/ome-common)
install(FILES ome-common-config.cmake DESTINATION cmake/ome-common)

 The `ome-common-config.cmake` should look like this:

include(CMakeFindDependencyMacro)
find_dependency(omedep)
include(${CMAKE_CURRENT_LIST_DIR}/ome-common-targets.cmake)

Note: for CMake versions < 3.0 you need to use `find_package` instead of
`find_dependency`.

Okay, so that's the solution if `ome-common`'s dependency creates an
imported lib target.

If `omedep` has an oldschool config-module which provides only variables
like OMEDEP_LIBRARIES containing absolute paths, then these paths will be
hardcoded in `ome-common-targets.cmake`. In this case the recommended
method is to convert these paths to relative paths in a postprocess step
after installation.
See this: https://gist.github.com/tamaskenez/7ca4cba352525985ea70 as an
example for such a script.

Of course this can only be used if `omedep` is a dependency which is
installed into the same install tree as `ome-common`.
If you have a dependency in a separate install-tree which does not create
imported lib targets then you need to do it yourself both in `ome-common`'s
CMakeLists.txt and config-modules. This is not a trivial operation but
always can be done with more or less additional logic. For a simple case
where `omedep` consists of a single library file:

`ome-common`'s CMakeLists.txt:

find_package(omedep REQUIRED)
add_library(ome-common::omedep STATIC IMPORTED) # STATIC or SHARED or
UNKNOWN
set_target_properties(ome-common::omedep PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${OMEDEP_INCLUDE_DIRS}
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION ${OMEDEP_LIBRARIES} # a single library
)
target_link_libraries(ome-common PUBLIC ome-common::omedep)
...

which should be repeated in `ome-common-config.cmake`:

include(CMakeFindDependencyMacro)
find_dependency(omedep)
set_target_properties(ome-common::omedep PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${OMEDEP_INCLUDE_DIRS}
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION ${OMEDEP_LIBRARIES} # a single library
)
include(${CMAKE_CURRENT_LIST_DIR}/ome-targets.cmake)

Things get more complicated when OMEDEP_LIBRARIES has per-config variants
or further dependencies. You can check the generated
`ome-common-targets.cmake` and `ome-common-targets-Debug/Relase.cmake`
files for an example on how to set up such an imported lib target.



On Sat, Nov 14, 2015 at 7:19 PM, Nicholas Braden  wrote:

> Instead of using FOO_INCLUDE_DIR, I believe you should use
> target_include_directories() with the INTERFACE or PUBLIC options -
> this will export the include directories properly and they will be
> used when someone target_link_library()s your exported target.
>
> https://cmake.org/cmake/help/latest/command/target_include_directories.html?highlight=INTERFACE
>
> There seems to be a section in the documentation on making sure your
> packages are relocatable:
>
> https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-relocatable-packages
>
> See also:
> https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html
>
> As for recursively finding packages, I honestly don't know on this
> front. I would imagine that everything might work if everything was
> using exported/imported targets, but I'm not sure. The problem is that
> you have to consider what happens if you relocate your relocatable
> package to a system that doesn't have the dependencies installed. I
> don't think exported/imported targets or relocatable packages can
> solve that problem easily, but I am not very knowledgeable in this
> area myself.
>
> On Sat, Nov 14, 2015 at 5:53 AM, Roger Leigh  wrote:
> > Hi,
> >
> > I'm wanting to create -config scripts for my libraries so that dependent
> > projects can find them with find_package and use them transparently.  I
> have
> > a number of header-only and shared/static libs, and I'd like to retain
> their
> > relationships, plus any additional libraries they are linked with.
> >
> > I was previously using hand-crafted templates, e.g. with this type of
> > generated structure:
> >
> >
> ---
> > set(OME_COMMON_FOUND TRUE)
> >
> > set(OME_COMMON_VERSION "5.2.0-pre0-7-gfc53ca3")
> > set(OME_COMMON_VERSION_MAJOR "5")
> > set(OME_COMMON_VERSION_MINOR "2")
> > set(OME_COMMON_VERSION_PATCH "0")
> > set

Re: [CMake] Creating relocatable export files

2015-11-14 Thread Nicholas Braden
Instead of using FOO_INCLUDE_DIR, I believe you should use
target_include_directories() with the INTERFACE or PUBLIC options -
this will export the include directories properly and they will be
used when someone target_link_library()s your exported target.
https://cmake.org/cmake/help/latest/command/target_include_directories.html?highlight=INTERFACE

There seems to be a section in the documentation on making sure your
packages are relocatable:
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-relocatable-packages

See also:
https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html

As for recursively finding packages, I honestly don't know on this
front. I would imagine that everything might work if everything was
using exported/imported targets, but I'm not sure. The problem is that
you have to consider what happens if you relocate your relocatable
package to a system that doesn't have the dependencies installed. I
don't think exported/imported targets or relocatable packages can
solve that problem easily, but I am not very knowledgeable in this
area myself.

On Sat, Nov 14, 2015 at 5:53 AM, Roger Leigh  wrote:
> Hi,
>
> I'm wanting to create -config scripts for my libraries so that dependent
> projects can find them with find_package and use them transparently.  I have
> a number of header-only and shared/static libs, and I'd like to retain their
> relationships, plus any additional libraries they are linked with.
>
> I was previously using hand-crafted templates, e.g. with this type of
> generated structure:
>
> ---
> set(OME_COMMON_FOUND TRUE)
>
> set(OME_COMMON_VERSION "5.2.0-pre0-7-gfc53ca3")
> set(OME_COMMON_VERSION_MAJOR "5")
> set(OME_COMMON_VERSION_MINOR "2")
> set(OME_COMMON_VERSION_PATCH "0")
> set(OME_COMMON_VERSION_EXTRA "-pre0-7-gfc53ca3")
>
> find_path(OME_COMMON_INCLUDE_DIR ome/common/module.h HINTS
> "/tmp/split/include")
> find_library(OME_COMMON_LIBRARY NAMES ome-common libome-common HINTS
> "/tmp/split/lib")
> ---
>
> They unfortuately did not handle interface targets or public library
> dependencies required by use in the headers.  I've switched to using
> install(EXPORT):
>
> https://github.com/rleigh-dundee/ome-common-cpp/blob/develop/lib/ome/common/CMakeLists.txt#L123
> ---
> target_link_libraries(ome-common ome-compat
>   ${Boost_LOG_SETUP_LIBRARY_RELEASE}
>   ${Boost_LOG_LIBRARY_RELEASE}
>   ${Boost_FILESYSTEM_LIBRARY_RELEASE}
>   ${Boost_SYSTEM_LIBRARY_RELEASE}
>   ${LibDl_LIBRARIES}
>   ${XercesC_LIBRARIES})
>
> set_target_properties(ome-common PROPERTIES LINKER_LANGUAGE CXX)
> set_target_properties(ome-common PROPERTIES VERSION ${OME_VERSION_SHORT})
>
> install(TARGETS ome-common
> EXPORT ome-common-config
> RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
> LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
> ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
> install(EXPORT ome-common-config
> DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/ome-common)
> ---
>
> This does a much better job of the dependencies.  It's preserving the
> dependencies for the internal targets, plus the external libraries. However,
> it's lacking:
>
> - any setting of the include path via FOO_INCLUDE_DIR, unless it's just not
> done in an obvious manner
> - it's hardcoded the absolute paths of the various boost and xerces libs;
> I'd like it to be relocatable so it can work in a superbuild and continue to
> work after moving elsewhere
> - it doesn't appear to recursively find needed import targets, e.g. I need
> to find_package(ome-compat) before find_package(ome-common); it would be
> nice if this was transparent so the user doesn't need to do this
>
> I'd be interested to know if anyone else has run into these issues, and if
> so what your solutions were?  I'm quite new to this part of cmake, so it may
> well just be I'm not doing things exactly as expected.
>
> Would it be easier to construct the template myself and then call
> find_package for the external libs to avoid hardcoding the paths?  Is it
> safe to recursively call find_package inside find_package?
>
>
> Thanks all,
> Roger
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/train

[CMake] Creating relocatable export files

2015-11-14 Thread Roger Leigh

Hi,

I'm wanting to create -config scripts for my libraries so that dependent 
projects can find them with find_package and use them transparently.  I 
have a number of header-only and shared/static libs, and I'd like to 
retain their relationships, plus any additional libraries they are 
linked with.


I was previously using hand-crafted templates, e.g. with this type of 
generated structure:


---
set(OME_COMMON_FOUND TRUE)

set(OME_COMMON_VERSION "5.2.0-pre0-7-gfc53ca3")
set(OME_COMMON_VERSION_MAJOR "5")
set(OME_COMMON_VERSION_MINOR "2")
set(OME_COMMON_VERSION_PATCH "0")
set(OME_COMMON_VERSION_EXTRA "-pre0-7-gfc53ca3")

find_path(OME_COMMON_INCLUDE_DIR ome/common/module.h HINTS 
"/tmp/split/include")
find_library(OME_COMMON_LIBRARY NAMES ome-common libome-common HINTS 
"/tmp/split/lib")

---

They unfortuately did not handle interface targets or public library 
dependencies required by use in the headers.  I've switched to using 
install(EXPORT):


https://github.com/rleigh-dundee/ome-common-cpp/blob/develop/lib/ome/common/CMakeLists.txt#L123
---
target_link_libraries(ome-common ome-compat
  ${Boost_LOG_SETUP_LIBRARY_RELEASE}
  ${Boost_LOG_LIBRARY_RELEASE}
  ${Boost_FILESYSTEM_LIBRARY_RELEASE}
  ${Boost_SYSTEM_LIBRARY_RELEASE}
  ${LibDl_LIBRARIES}
  ${XercesC_LIBRARIES})

set_target_properties(ome-common PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(ome-common PROPERTIES VERSION ${OME_VERSION_SHORT})

install(TARGETS ome-common
EXPORT ome-common-config
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
install(EXPORT ome-common-config
DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/ome-common)
---

This does a much better job of the dependencies.  It's preserving the 
dependencies for the internal targets, plus the external libraries. 
However, it's lacking:


- any setting of the include path via FOO_INCLUDE_DIR, unless it's just 
not done in an obvious manner
- it's hardcoded the absolute paths of the various boost and xerces 
libs; I'd like it to be relocatable so it can work in a superbuild and 
continue to work after moving elsewhere
- it doesn't appear to recursively find needed import targets, e.g. I 
need to find_package(ome-compat) before find_package(ome-common); it 
would be nice if this was transparent so the user doesn't need to do this


I'd be interested to know if anyone else has run into these issues, and 
if so what your solutions were?  I'm quite new to this part of cmake, so 
it may well just be I'm not doing things exactly as expected.


Would it be easier to construct the template myself and then call 
find_package for the external libs to avoid hardcoding the paths?  Is it 
safe to recursively call find_package inside find_package?



Thanks all,
Roger
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake