View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0011160CMakeModulespublic2010-08-23 10:412010-11-09 22:57
ReporterRaffi Enficiaud 
Assigned ToPhilip Lowman 
PrioritynormalSeverityfeatureReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product VersionCMake-2-8 
Target VersionCMake 2.8.3Fixed in VersionCMake 2.8.3 
Summary0011160: FindBoost to retrieve realpath of the boost libraries
DescriptionHello,

I would like to install some of the boost components with cpack from my cmake project.
In order to create a package on Linux targets, I use for instance the following commands:

set(BoostFilesToInstall
  ${Boost_PYTHON_LIBRARY_RELEASE}
  ${Boost_SYSTEM_LIBRARY_RELEASE}
  ${Boost_GRAPH_LIBRARY_RELEASE}
  )
install(FILES
  ${BoostFilesToInstall}
  CONFIGURATIONS Release
  DESTINATION lib
  COMPONENT libraries)

However, FindBoost retrieves the links to the boost compiled libraries, rather than the files
pointed by these links. The building of a debian/mac os bundle package complain about that.
I am not 100% sure but I think cpack is trying to install the links rather than the files themselves.

So I was wondering if it would be possible to have as ${Boost_XXX_LIBRARY} libraries the result of
get_filename_component(Boost_XXX_LIBRARY ${Boost_XXX_LIBRARY} REALPATH). This way, the package would
be consistent and the dependant libraries in my project will link with boost libraries named explicitely
with their version, compiler etc.

Do you think it is a good thing to have, or the fact that using the link name is desired behaviour ?

Kind regards,
Raffi Enficiaud
TagsNo tags attached.
Attached Files? file icon FindBoost.cmake.1 [^] (49,968 bytes) 2010-09-08 00:44
? file icon FindBoost.cmake [^] (50,214 bytes) 2010-09-13 10:10

 Relationships

  Notes
(0022052)
Philip Lowman (developer)
2010-09-01 01:20

Raffi,

I believe the existing behavior is desired. That is, Boost_XXX_LIBRARY is a symbolic link that resolves to a versioned shared library. Your application when compiled should automatically depend on the resolved symbolic link with the version information (you can check this by using the "ldd" program to see what shared libraries your executable depends on).

For example. The program foo, which is compiled like this:

cmake_minimum_required(VERSION 2.6)
project(Foo)
find_package(Boost 1.40 REQUIRED serialization)
add_executable(foo foo.cc)
target_link_libraries(foo ${Boost_SERIALIZATION_LIBRARY})

Given a filesystem like this:
lowman@ubuntu:~/cmaketests/boost/build$ ls -l /usr/lib/libboost_serialization*
-rw-r--r-- 1 root root 1259538 2009-10-20 15:44 /usr/lib/libboost_serialization.a
lrwxrwxrwx 1 root root 24 2010-01-05 00:50 /usr/lib/libboost_serialization-mt.a -> libboost_serialization.a
lrwxrwxrwx 1 root root 32 2010-01-05 00:50 /usr/lib/libboost_serialization-mt.so -> libboost_serialization.so.1.40.0
lrwxrwxrwx 1 root root 32 2010-01-05 00:50 /usr/lib/libboost_serialization.so -> libboost_serialization.so.1.40.0
-rw-r--r-- 1 root root 466960 2009-10-20 15:44 /usr/lib/libboost_serialization.so.1.40.0

Produces dependencies like this for me:
lowman@ubuntu:~/cmaketests/boost/build$ ldd foo
    linux-vdso.so.1 => (0x00007fff53e71000)
    libboost_serialization.so.1.40.0 => /usr/lib/libboost_serialization.so.1.40.0 (0x00007f5f52847000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f5f52537000)
    libm.so.6 => /lib/libm.so.6 (0x00007f5f522b3000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f5f5209c000)
    libc.so.6 => /lib/libc.so.6 (0x00007f5f51d2c000)
    librt.so.1 => /lib/librt.so.1 (0x00007f5f51b24000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x00007f5f51908000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f5f52ab9000)

I think if you want CPack to package up the followed symbolic links, that may be a bit more difficult as I assume the REALPATH flag you mentioned follows the symlink through any intermediate symlinks that might be needed. It may work OK for Boost if they don't use two levels of symlink following, however.

If you want to submit a patch to FindBoost that optionally sets new variables that you can use later in CPack (e.g. Boost_FOO_LIBRARY_REALPATH) I would welcome it. It would need to be configurable so it's not on by default. Also it would have to gracefully handle the fact that Boost_FOO_LIBRARY contains debug/optimized keywords under certain platforms like MSVC.
(0022095)
Raffi Enficiaud (developer)
2010-09-06 04:45

Dear M. Lowman,

Thank you for your answer. I agree with you with the fact that such a behavior works quite well with the runtime (ldd) and that it might need some work to make it work properly with CPack (in fact, to make it coherent, unless CPack follows the symlinks).

Currently, I bypass the CPack problem by installing "renamed" libraries: I follow the symlinks and install the true target with the name of the symlink. The macro for doing that is as follow:

----------------
function(install_realpath_with_rename file_names path_to_install component configuration)
 foreach(loop_var ${file_names})
  get_filename_component(filepathreal ${loop_var} REALPATH)
  get_filename_component(filename ${loop_var} NAME)
  
  if(NOT EXISTS ${filepathreal})
   message("file ${filepathreal} does not EXISTS !!!")
  endif()
  install(FILES ${loop_var} CONFIGURATIONS ${configuration} DESTINATION ${path_to_install} COMPONENT ${component} RENAME ${filename})
 endforeach()
endfunction(install_realpath_with_rename)
----------------

and is invoked like this

----------------
set(BoostFilesToInstall
  ${Boost_PYTHON_LIBRARY_RELEASE}
  ${Boost_SYSTEM_LIBRARY_RELEASE}
  ${Boost_GRAPH_LIBRARY_RELEASE}
  ${Boost_REGEX_LIBRARY_RELEASE}
  ${Boost_DATE_TIME_LIBRARY_RELEASE}
  ${Boost_FILESYSTEM_LIBRARY_RELEASE}
  ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}
  )
install_realpath_with_rename("${BoostFilesToInstall}" lib libraries Release)
---------------

As you have noticed, this is not very elegant and does not take into account the optimized/debug options, but it has the advantage of using the variables of FindBoost work as defined in the design. As I install only release versions, it worked also fine for me concerning the optimized/debug options.
The other solution was to install the symlinks along with the targets (again, by using a macro), which is similar to what I am obliged to do under windows (libs and dlls). But in my opinion, it is a bit redundant.


If we get back to "improving" (if I can help) FindBoost, what I can propose as a patch is to define a variable that forces FindBoost to follow the symlinks, rather than defining new targets such as Boost_FOO_LIBRARY_REALPATH as you suggested. It has the main advantage of being non-intrusive in the existing design and cmake scripts.

I think this can be very easily achieved by doing this in FindBoost.cmake, line 436, replace

---------------
FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
  NAMES ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}-${Boost_LIB_VERSION}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_STATIC_TAG}-${Boost_LIB_VERSION}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}
  HINTS ${_boost_LIBRARIES_SEARCH_DIRS}
)
---------------

by something like

---------------
FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
  NAMES ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}-${Boost_LIB_VERSION}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_STATIC_TAG}-${Boost_LIB_VERSION}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}
         ${Boost_LIB_PREFIX}boost_${COMPONENT}
  HINTS ${_boost_LIBRARIES_SEARCH_DIRS}
)

if(Boost_REALPATH)
  if(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE) # was it found ?
    get_filename_component(filepathreal Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE REALPATH)
    set(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE ${filepathreal})
  endif()
endif(Boost_REALPATH)
---------------

(+ same for debug)
where Boost_REALPATH is a variable defined by the user (non defined by default) that forces FindBoost to has this behavior. Since the calls to _Boost_ADJUST_LIB_VARS are using these variables, I guess everything would work as expected and currently designed.

If you agree with this proposition, I have to check what happens exactly with the cache and propose you a "clean" version.


Kind regards,
Raffi Enficiaud
(0022125)
Philip Lowman (developer)
2010-09-08 00:44

I suggested the additional *_REALPATH variables because I wasn't sure if users might need access to the symbolic links in addition to the resolved files?

I've included your change in this more recent FindBoost I've been hacking on for another couple of issues. It doesn't appear to work as expected (not sure why, it might have something to do with trying to overwrite the cache variable with a local one?).

Please base any patches or modified versions off of the attached version if possible.
(0022208)
Raffi Enficiaud (developer)
2010-09-13 10:09

Dear M. Lowman,

Here is the patch:
if(Boost_REALPATH)
  if(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE) # was it found ?
    get_filename_component(_boost_filepathreal ${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE} REALPATH)
    unset(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE CACHE)
    set(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE ${_boost_filepathreal} CACHE FILEPATH "Boost ${UPPERCOMPONENT} component (release)")
    message("Release = ${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}")
  endif()

  if(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG) # was it found ?
    get_filename_component(_boost_filepathreal ${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG} REALPATH)
    unset(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG CACHE)
    set(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG ${_boost_filepathreal} CACHE FILEPATH "Boost ${UPPERCOMPONENT} component (debug)")
    message("Debug = ${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}")
  endif()
endif()

This is not very elegant, but basically the variables should be overwritten in the cache.

I tested it with the original version of FindBoost.cmake (cmake 2.8.2) and the version you provided in this thread on a MACOSX. It seems to work but I was not able to get the debug version with your file (it worked as expected with the original FindBoost). BTW I should also test the file with an Ubuntu distrib since the problems seem to appear on this platform. It should work *in theory* but every body knows the difference between theory and practice.


Regards,
Raffi
(0022262)
Philip Lowman (developer)
2010-09-18 12:06

I've tested the behavior on Ubuntu and it works fine. I refactored the code into a function and modified the documentation on the _RELEASE and _DEBUG cache variables to be consistent. Thanks.


diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index ff3e17b..7acd31a 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -155,7 +155,16 @@
 # might be found if you specified "win32" here before
 # falling back on libboost_thread-mgw45-mt-1_43.a.
 # [Since CMake 2.8.3]
-
+#
+# Boost_REALPATH Resolves symbolic links for discovered boost libraries
+# to assist with packaging. For example, instead of
+# Boost_SYSTEM_LIBRARY_RELEASE being resolved to
+# "/usr/lib/libboost_system.so" it would be
+# "/usr/lib/libboost_system.so.1.42.0" instead.
+# This does not affect linking and should not be
+# enabled unless the user needs this information.
+# [Since CMake 2.8.3]
+#
 
 
 #
@@ -342,6 +351,17 @@ function(_Boost_PREPEND_LIST_WITH_THREADAPI _output)
 endfunction()
 
 #
+# If a library is found, replace its cache entry with its REALPATH
+#
+function(_Boost_SWAP_WITH_REALPATH _library _docstring)
+ if(${_library})
+ get_filename_component(_boost_filepathreal ${${_library}} REALPATH)
+ unset(${_library} CACHE)
+ set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}")
+ endif()
+endfunction()
+
+#
 # End functions/macros
 #
 #-------------------------------------------------------------------------------
@@ -863,6 +883,9 @@ ELSE (_boost_IN_CACHE)
     set( Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE-NOTFOUND" )
     set( Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG-NOTFOUND")
 
+ set( _boost_docstring_release "Boost ${COMPONENT} library (release)")
+ set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)")
+
     #
     # Find RELEASE libraries
     #
@@ -891,6 +914,7 @@ ELSE (_boost_IN_CACHE)
         NAMES ${_boost_RELEASE_NAMES}
         HINTS ${_boost_LIBRARY_SEARCH_DIRS}
         ${_boost_FIND_OPTIONS}
+ DOC "${_boost_docstring_release}"
     )
 
     #
@@ -921,9 +945,16 @@ ELSE (_boost_IN_CACHE)
         NAMES ${_boost_DEBUG_NAMES}
         HINTS ${_boost_LIBRARY_SEARCH_DIRS}
         ${_boost_FIND_OPTIONS}
+ DOC "${_boost_docstring_debug}"
     )
 
+ if(Boost_REALPATH)
+ _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}")
+ _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "${_boost_docstring_debug}" )
+ endif()
+
     _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT})
+
   endforeach(COMPONENT)
 
   # Restore the original find library ordering

 Issue History
Date Modified Username Field Change
2010-08-23 10:41 Raffi Enficiaud New Issue
2010-09-01 00:51 Philip Lowman Status new => assigned
2010-09-01 00:51 Philip Lowman Assigned To => Philip Lowman
2010-09-01 01:20 Philip Lowman Note Added: 0022052
2010-09-01 01:20 Philip Lowman Severity minor => feature
2010-09-06 04:45 Raffi Enficiaud Note Added: 0022095
2010-09-08 00:44 Philip Lowman Note Added: 0022125
2010-09-08 00:44 Philip Lowman File Added: FindBoost.cmake.1
2010-09-13 10:09 Raffi Enficiaud Note Added: 0022208
2010-09-13 10:10 Raffi Enficiaud File Added: FindBoost.cmake
2010-09-18 11:59 Philip Lowman Target Version => CMake 2.8.3
2010-09-18 12:06 Philip Lowman Note Added: 0022262
2010-09-18 12:06 Philip Lowman Status assigned => resolved
2010-09-18 12:06 Philip Lowman Fixed in Version => CMake 2.8.3
2010-09-18 12:06 Philip Lowman Resolution open => fixed
2010-11-09 22:57 Philip Lowman Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team