View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0012382 | CMake | Modules | public | 2011-08-02 18:47 | 2016-06-10 14:31 | ||||
Reporter | Gregory Crosswhite | ||||||||
Assigned To | Kitware Robot | ||||||||
Priority | normal | Severity | minor | Reproducibility | always | ||||
Status | closed | Resolution | moved | ||||||
Platform | Apple Mac | OS | OS X | OS Version | 10.4.10 | ||||
Product Version | CMake 2.8.5 | ||||||||
Target Version | Fixed in Version | ||||||||
Summary | 0012382: fixup_bundle_item dies on libraries copied to a directory outside bundle directory | ||||||||
Description | When using a Linux-style layout for the installation with bin/, lib/, etc. and directing the required shared libraries to be installed in lib/ instead of bin/, fixup_bundle_item does not recognize that they have been installed into the bundle and reports a fatal error. The problem comes from the fact that when calling fixup_bundle on an executable in the bin/ directory, fixup_bundle sets the bundle directory to bin/ which is a sibling but not a parent of lib/, and so fixup_bundle_item does not recognize that the library it is fixing up has already been put in the bundle. | ||||||||
Steps To Reproduce | The attached file has an example setup that triggers the issue; inside the ZIPfile are three files which are listed below: ===== 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 @ONLY ) install(SCRIPT ${CMAKE_BINARY_DIR}/FixBundle.cmake) ===== FixBundle.cmake ===== 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) fixup_bundle("${CMAKE_INSTALL_PREFIX}/bin/hello${CMAKE_EXECUTABLE_SUFFIX}" "" "@LIBRARY_OUTPUT_PATH@") ===== hello.cpp ===== #include <iostream> using namespace std; int main() { cout << "Hello, world!" << endl; return 0; } ====================== Note that hello.cpp doesn't use Boost, I just included the dependency in order to make sure that an external non-system shared library was pulled in. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | cmake-issue-example.zip [^] (1,342 bytes) 2011-08-02 18:47 cmake-issue-example-2.zip [^] (1,396 bytes) 2011-08-02 19:12 | ||||||||
Relationships | ||||||
|
Relationships |
Notes | |
(0027151) Gregory Crosswhite (reporter) 2011-08-02 19:12 |
Note that this problem is triggered even when there are *no* outside shared libraries being pulled in if a build shared library is listed in the second argument of fixup_bundle but is not installed in the executable directory. See cmake-issue-example-2.zip for this; libhello.cpp is empty, and CMakeLists.txt and FixBundle.cmake.in are as follows: ===== CMakeLists.txt ===== cmake_minimum_required(VERSION 2.8.5) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/bundle) add_executable(hello hello) add_library(hellolib SHARED hellolib) install (TARGETS hello DESTINATION bin) install (TARGETS hellolib DESTINATION lib) configure_file( ${CMAKE_SOURCE_DIR}/FixBundle.cmake.in ${CMAKE_BINARY_DIR}/FixBundle.cmake @ONLY ) install(SCRIPT ${CMAKE_BINARY_DIR}/FixBundle.cmake) ===== FixBundle.cmake.in ===== include (BundleUtilities) fixup_bundle( "${CMAKE_INSTALL_PREFIX}/bin/hello@CMAKE_EXECUTABLE_SUFFIX@" "${CMAKE_INSTALL_PREFIX}/lib/@CMAKE_SHARED_LIBRARY_PREFIX@hellolib@CMAKE_SHARED_LIBRARY_SUFFIX@" "@LIBRARY_OUTPUT_PATH@" ) ===================== The resulting error message is ===================== -- Install configuration: "" -- Up-to-date: /Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello -- Installing: /Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/lib/libhellolib.dylib -- fixup_bundle -- app='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello' -- libs='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/lib/libhellolib.dylib' -- dirs='' -- fixup_bundle: preparing... -- fixup_bundle: copying... -- 1/4: *NOT* copying '/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/lib/libhellolib.dylib' -- 2/4: *NOT* copying '/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/hello' -- fixup_bundle: fixing... -- 3/4: fixing up '/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/lib/libhellolib.dylib' exe_dotapp_dir/='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/bin/' item_substring='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/lib/' resolved_embedded_item='/Users/gcross/Documents/ThrowawayCode/cmake-issue-example/build/bundle/lib/libhellolib.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:3 (fixup_bundle) cmake_install.cmake:54 (INCLUDE) ===================== |
(0027152) Gregory Crosswhite (reporter) 2011-08-02 19:13 |
It seems to me like the best way to resolve this is to let the user override the way that the bundle directory is obtained from the path to the executable; this would also cause fixup_bundle to correctly scan through the entire bundle looking for libraries rather than just the subdirectory containing the executable specified in the first parameter of fixup_bundle. |
(0027153) Clinton Stimpson (developer) 2011-08-02 19:33 |
The fix for this bug is to modify the check that throws the "Install or copy..." error. |
(0027154) Gregory Crosswhite (reporter) 2011-08-02 19:49 |
Okidoke; you're the developer, not me. :-) |
(0030269) David Cole (manager) 2012-08-11 11:28 |
Clinton, How should we modify this? The intent everywhere is to make sure the final bundle is truly stand-alone and may be relocated to another machine and another root directory and still work. The intent on Mac was to make sure all files are contained within the .app directory structure to ensure that it is "stand-alone". The intent on Windows is to make sure *all* files are in *the same* directory so that DLL loading "just works". What is the intent with "fixup_bundle" on Linux? Is *any* directory structure ok, and if so, how do know the "bundle" will work when it is simply copied/moved to a new machine/location on Linux? I'd be happy to take this one, but I still don't have a good grasp on how useful this is on Linux. One of these days, I've got to get into building my own little bundle example app on Linux, so I have a little sandbox app that I understand fully. Thanks... |
(0030323) Clinton Stimpson (developer) 2012-08-11 12:45 |
BundleUtilities is likely less popular on Linux, and is most likely used by those shipping their own binaries with their own 3rd party libraries which may or may not exist on any given target machine. I don't think these users are bound to the bin/ lib/ convention, since the intent of BundleUtilities is to make a relocatable/standalone application. Any directory structure is allowed on Linux when using rpaths. When using a bin/ lib/ structure, an executable can have an rpath of "$ORIGIN/../lib" so any dependent shared library will be found. For a plugin down in "plugins/typeA/" directory, it could have an rpath of $ORIGIN/../../lib to find its dependencies. So, if one were to copy/move the parent directory (containing bin/ lib/ plugins/), it would still work. We had a discussion a while back about the user passing in a prefix which could be different than the executable directory or the .app directory. Perhaps that is the solution we need here. That would also fix this one: http://www.cmake.org/Bug/view.php?id=13052. [^] I'd also like to see full @rpath support someday on the Mac, and move away from @executable_path. Perhaps if you took the time to use @rpath on Mac, you would fully understand rpaths on Linux. Though on Linux, its a bit simpler. |
(0030324) Clinton Stimpson (developer) 2012-08-11 12:47 |
Oh, I just realized the Reporter is on Mac, not Linux, which means this is even more similar to bug 0013052. |
(0031656) David Cole (manager) 2012-11-21 14:57 |
Un-assigning bugs that are not on the active roadmap, which no developers are actively working on for the CMake 2.8.11 release. If one gets put back on the roadmap, re-assign it appropriately at that time. |
(0031663) David Cole (manager) 2012-11-21 15:11 |
Re-setting status back to "new" for bugs that are "assigned" but not assigned to a specific developer. When/if these bugs go back on the roadmap for a specific version, assignment to an appropriate developer should take place then... |
(0032915) Craig Scott (reporter) 2013-04-22 01:27 |
Any chance this one can make it back on someone's todo list? I've hit exactly this scenario on linux. We have a bin/ lib/ structure and we use the include(InstallRequiredSystemLibraries) feature to ensure we get packages which are fully self-contained. We use an RPATH of $ORIGIN/../lib as described by Clinton. The arrangement works well on Windows and would probably work well on Mac, but on linux it means the install step is broken because it doesn't find libraries in lib/. Strangely, the install step copies duplicates of those libraries into bin/ which is probably a direct consequence, but that just makes it even harder to understand why the verify_app step fails! Not sure if it's related, but it might also be worth reviewing bug 0013433 just in case it is relevant. Personally though, I suspect the problem is more related to the fact that the RPATH substitution results in a full path containing /../ and somewhere in the CMake code it compares this against a canonical path or something similar. |
(0040459) Florian Apolloner (reporter) 2016-02-10 08:49 |
@Craig: I've fixed it like this for me: set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib") set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/BAPGui") install(TARGETS bap-gui DESTINATION bin) get_target_property(QMAKE_PATH Qt5::qmake IMPORTED_LOCATION) execute_process(COMMAND ${QMAKE_PATH} -query QT_INSTALL_PREFIX OUTPUT_VARIABLE QT_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) install(CODE " function(gp_item_default_embedded_path_override item path_var) set(\${path_var} \"@executable_path/../lib\" PARENT_SCOPE) endfunction() function(gp_resolved_file_type_override item type_var) if(\${item} MATCHES \"\\\\.\\\\./lib\") set(\${type_var} \"local\" PARENT_SCOPE) endif() endfunction() include(${CMAKE_CURRENT_SOURCE_DIR}/BundleUtilitiesLocal.cmake) fixup_bundle(\"\$ENV{DESTDIR}/\${CMAKE_INSTALL_PREFIX}/bin/bap-gui\" \"\" \"${QT_PREFIX}/lib\") ") set(CPACK_GENERATOR "TGZ") |
(0041881) Kitware Robot (administrator) 2016-06-10 14:28 |
Resolving issue as `moved`. This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page. |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2011-08-02 18:47 | Gregory Crosswhite | New Issue | |
2011-08-02 18:47 | Gregory Crosswhite | File Added: cmake-issue-example.zip | |
2011-08-02 19:12 | Gregory Crosswhite | Note Added: 0027151 | |
2011-08-02 19:12 | Gregory Crosswhite | File Added: cmake-issue-example-2.zip | |
2011-08-02 19:13 | Gregory Crosswhite | Note Added: 0027152 | |
2011-08-02 19:33 | Clinton Stimpson | Note Added: 0027153 | |
2011-08-02 19:49 | Gregory Crosswhite | Note Added: 0027154 | |
2012-08-11 11:24 | David Cole | Assigned To | => David Cole |
2012-08-11 11:24 | David Cole | Status | new => assigned |
2012-08-11 11:28 | David Cole | Note Added: 0030269 | |
2012-08-11 12:45 | Clinton Stimpson | Note Added: 0030323 | |
2012-08-11 12:47 | Clinton Stimpson | Note Added: 0030324 | |
2012-08-11 17:08 | David Cole | Relationship added | related to 0013052 |
2012-11-21 14:57 | David Cole | Note Added: 0031656 | |
2012-11-21 15:00 | David Cole | Assigned To | David Cole => |
2012-11-21 15:11 | David Cole | Status | assigned => new |
2012-11-21 15:11 | David Cole | Note Added: 0031663 | |
2013-04-22 01:27 | Craig Scott | Note Added: 0032915 | |
2016-02-10 08:49 | Florian Apolloner | Note Added: 0040459 | |
2016-06-10 14:28 | Kitware Robot | Note Added: 0041881 | |
2016-06-10 14:28 | Kitware Robot | Status | new => resolved |
2016-06-10 14:28 | Kitware Robot | Resolution | open => moved |
2016-06-10 14:28 | Kitware Robot | Assigned To | => Kitware Robot |
2016-06-10 14:31 | Kitware Robot | Status | resolved => closed |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |