[CMake] Gathering up required shared libraries

Gregory Crosswhite gcrosswhite at gmail.com
Tue Aug 2 17:38:01 EDT 2011


On 8/2/11 1:09 PM, Clinton Stimpson wrote:
> Ok, can you make an example that demonstrates the problem?
>
> I think this should work without overriding get_dotapp_dir() in
> BundleUtilities.
>

The example is attached to this e-mail.  I don't actually use Boost in 
this example except as a means of pulling in a dependency on a 
non-system shared library, so if necessary replace all references to it 
in CMakeLists.txt with some other package on your system that will 
generate a dependency on a non-system shared library in order to see 
something akin to what I am seeing.

My CMakeLists.txt file looks like this:

======== CMakeLists.txt ========
cmake_minimum_required(VERSION 2.8.5)

set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/bundle)

find_package( Boost COMPONENTS thread REQUIRED )
link_directories ( ${Boost_LIBRARY_DIRS} )
include_directories ( ${Boost_INCLUDE_DIRS} )

add_executable(hello hello)
target_link_libraries(hello ${Boost_LIBRARIES})
install (TARGETS hello RUNTIME DESTINATION bin)

configure_file(
     ${CMAKE_SOURCE_DIR}/FixBundle.cmake.in
     ${CMAKE_BINARY_DIR}/FixBundle.cmake
)
install(SCRIPT ${CMAKE_BINARY_DIR}/FixBundle.cmake)
=============================

The file FixBundle.cmake.in looks like this:

======== FixBundle.cmake.in ========
include (BundleUtilities)

function(gp_item_default_embedded_path item default_embedded_path_var)
   set(${default_embedded_path_var} "@executable_path/../lib" PARENT_SCOPE)
endfunction(gp_item_default_embedded_path)

# VERSION 1
#fixup_bundle("${CMAKE_INSTALL_PREFIX}" "" "@LIBRARY_OUTPUT_PATH@")

# VERSION 2
fixup_bundle("${CMAKE_INSTALL_PREFIX}/bin/hello${CMAKE_EXECUTABLE_SUFFIX}" 
"" "@LIBRARY_OUTPUT_PATH@")
=============================

Note that I override the path where libraries are copied.  Also note 
that there are two versions of me calling fixup_bundle.  In the first 
version, I pass in the installation directory as the first argument to 
fixup_bundle --- that is, where bin/ and lib/ are supposed to be put.  
This causes an error message like the following to be displayed:

====== VERSION 1 ERROR MESSAGE ======
-- Install configuration: ""
-- Up-to-date: 
/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello
-- fixup_bundle
--   
app='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle'
--   libs=''
--   dirs=''
-- warning: *NOT* handled - directory but not .app case...
CMake Error at /Applications/CMake 
2.8-5.app/Contents/share/cmake-2.8/Modules/BundleUtilities.cmake:668 
(message):
   error: fixup_bundle: not a valid bundle
Call Stack (most recent call first):
   FixBundle.cmake:8 (fixup_bundle)
   cmake_install.cmake:41 (INCLUDE)
==============================

In the second version (commented out in in the attached file), I pass in 
the path to where the "hello" executable is installed.  This causes an 
error message like the following to be displayed:

====== VERSION 2 ERROR MESSAGE ======
-- Install configuration: ""
-- Up-to-date: 
/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello
-- fixup_bundle
--   
app='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello'
--   libs=''
--   dirs=''
-- fixup_bundle: preparing...
-- fixup_bundle: copying...
-- 1/4: *NOT* copying 
'/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello'
-- 2/4: copying '/opt/local/lib/libboost_thread-mt.dylib'
Error copying file "/opt/local/lib/libboost_thread-mt.dylib" to 
"/libboost_thread-mt.dylib".
-- fixup_bundle: fixing...
-- 3/4: fixing up 
'/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello'
-- 4/4: fixing up '/libboost_thread-mt.dylib'
   
exe_dotapp_dir/='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/'
   item_substring=''
   resolved_embedded_item='/libboost_thread-mt.dylib'

Install or copy the item into the bundle before calling fixup_bundle.
Or maybe there's a typo or incorrect path in one of the args to 
fixup_bundle?

CMake Error at /Applications/CMake 
2.8-5.app/Contents/share/cmake-2.8/Modules/BundleUtilities.cmake:568 
(message):
   cannot fixup an item that is not in the bundle...
Call Stack (most recent call first):
   /Applications/CMake 
2.8-5.app/Contents/share/cmake-2.8/Modules/BundleUtilities.cmake:656 
(fixup_bundle_item)
   FixBundle.cmake:11 (fixup_bundle)
   cmake_install.cmake:41 (INCLUDE)
==============================

As you can see, neither version works.  The first version doesn't work 
because fixup_bundle requires an executable file rather than a 
directory, and the second version doesn't work because it sets the 
bundle directory to bin/ *inside* of the installation prefix and so it 
doesn't see that the libraries are also inside the bundle.

Thoughts?  In particular, is there a third option I have missed, or am I 
correct that the only way around this issue is for me to override 
get_dotapp_dir() or some other function in BundleUtilities.cmake?

Thanks again for your help everyone!  :-)
Cheers,
Greg
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cmake-issue-example.zip
Type: application/zip
Size: 1355 bytes
Desc: not available
URL: <http://www.cmake.org/pipermail/cmake/attachments/20110802/492a0d2a/attachment-0001.zip>


More information about the CMake mailing list