[CMake] fixup_bundles on macosx for non-.app target

Michael Jackson mike.jackson at bluequartz.net
Mon Sep 14 23:19:08 EDT 2015


Sorry for the delay. 
  https://github.com/dream3d/DREAM3D/tree/develop/Support/cmp/OSX_Tools

the CompleteTool.cmake.in calls the CompleteTool.sh.in files through a custom cmake command after they are "Configured" through "configure_file". I think you can figure out what is going on. There may be some issues with the shell script regarding temp file cleanup but it generally works. We build and package every night on our build systems.

Mike Jackson

On Sep 12, 2015, at 11:07 PM, Seth Cantrell <seth.cantrell at gmail.com> wrote:

> Please, I would like to see that script template. I'm also looking at the source for BundleUtilities. It seems like it shouldn't be difficult to make a module that provides the generic functionality  across platforms.
> 
>> On Sep 12, 2015, at 9:09 PM, Michael Jackson <mike.jackson at bluequartz.net> wrote:
>> 
>> I have a mix of .app and command line executables for our project on OS X. I wrote a templated .sh file that cmake uses to “configure_file()” by filling in details needed. The Script itself does the “fix up” stuff by running otool, parsing the output, looking for the libraries and then updating everything. You are welcome to the script if you find it useful.
>> 
>> Mike Jackson
>> 
>>> On Sep 12, 2015, at 7:54 PM, Seth Cantrell <seth.cantrell at gmail.com> wrote:
>>> 
>>>> 
>>>> On Sep 12, 2015, at 5:28 PM, Dan Kegel <dank at kegel.com> wrote:
>>>> 
>>>> On Sat, Sep 12, 2015 at 1:52 PM, Seth Cantrell <seth.cantrell at gmail.com> wrote:
>>>>> I have a project which uses fixup_bundle on Windows to package up the exe with the third-party dlls it requires. On Mac OS X this same packaging process fails. It looks like on Mac OS X this utility is assuming I want to producing a .app bundle.
>>>> 
>>>> Given that a .app bundle is just a directory containing the executable and
>>>> the things it depends on, what's wrong with what fixup_bundle does?
>>>> Do you have a special reason to not want to follow the .app convention?
>>>> - Dan
>>> 
>>> The primary problem is simply that install and CPack processes fail on Mac OS X. If I can get the process to succeed, even if that means producing a .app directory structure for this non-.app, command line executable that would be a fine first step. But ultimately I'd rather not have to fake the .app structure either.
>>> 
>>> On Windows installing and packaging succeed. For example on windows I get a .zip file named myproj-0.1.1-win64.zip that contains:
>>> 
>>> myproj-0.1.1-win64.zip\
>>> myproj-0.1.1-win64\
>>>  main.exe
>>>  somelib.dll
>>>  someotherlib.dll
>>> 
>>> And of course the _CPack_Packages structure used to generate this is
>>> 
>>> _CPack_Packages\
>>> win64\
>>>  ZIP\
>>>    myproj-0.1.1-win64\
>>>      main.exe
>>>      somelib.dll
>>>      someotherlib.dll
>>> 
>>> This is the same structure I'd like to produce on OS X.
>>> 
>>> On Mac OS X the packaging process fails:
>>> 
>>>> [1/1] Run CPack packaging tool...
>>>> CPack: Create package using ZIP
>>>> CPack: Install projects
>>>> CPack: - Install project: scratch
>>>> exe_dotapp_dir/='/Volumes/D/Builds/scratch/_CPack_Packages/Darwin/ZIP/scratch-0.1.1-Darwin/'
>>>> item_substring='/Volumes/D/Builds/scratch/_CPack_Packages/Darwin/ZIP/MacOS/somelib'
>>>> resolved_embedded_item='/Volumes/D/Builds/scratch/_CPack_Packages/Darwin/ZIP/MacOS/somelib.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.app/Contents/share/cmake-3.3/Modules/BundleUtilities.cmake:737 (message):
>>>> cannot fixup an item that is not in the bundle...
>>>> Call Stack (most recent call first):
>>>> /Applications/CMake.app/Contents/share/cmake-3.3/Modules/BundleUtilities.cmake:848 (fixup_bundle_item)
>>>> /Volumes/D/Builds/scratch/FixBundle.cmake:11 (fixup_bundle)
>>>> /Volumes/D/Builds/scratch/cmake_install.cmake:41 (include)
>>>> 
>>>> 
>>>> CPack Error: Error when generating package: scratch
>>>> FAILED: cd /Volumes/D/Builds/scratch && /Applications/CMake.app/Contents/bin/cpack --config ./CPackConfig.cmake
>>>> ninja: build stopped: subcommand failed.
>>> 
>>> On Mac OS X after the packaging failure I can see that _CPack_Packages contains a directory structure
>>> 
>>> _CPack_Packages\
>>> Darwin\
>>>  ZIP\
>>>    MacOS\
>>>      somelib.dylib
>>>      someotherlib.dylib
>>>    myproj-0.1.1-Darwin\
>>>      main
>>> 
>>> and the process has stopped before generating the zip file.
>>> 
>>> The initial error is due to the fact that I'm putting the executable in the root of the install tree: install(TARGETS main DESTINATION "."). This causes fixup_bundle's behavior on Mac OS to put the libraries outside the directory that CPack is preparing to zip, causing an error where fixup (quite correctly) refuses to work when the dylibs aren't in the directory that's going to be zipped up
>>> 
>>> Even so, the packaging process has clearly gone as far as correctly identifying the dylibs and copying them into the _CPack_Packages directory. Using otool I can see that the executable's rpath's for finding the dylibs have been updated: @executable_path/../MacOS/somelib.dylib. Using DYLD_PRINT_LIBRARIES I can see that running the executable does indeed load the intended .dylibs the the program runs correctly.
>>> 
>>> Trying to fix the issue of the dylibs being put outside the zip directory, I changed the install command to not put the executable at the root of the install location: install(TARGET main DESTINATION "bin"). This still does not succeed because fixup_bundle is explicitly verifying whether the directory structure is a valid bundle, which this is not.
>>> 
>>>> CMake Error at /Applications/CMake.app/Contents/share/cmake-3.3/Modules/BundleUtilities.cmake:860 (message):
>>>> error: fixup_bundle: not a valid bundle
>>> 
>>> And of course just trying to ape the .app directory structure still does not produce a valid .app bundle: install(TARGETS main DESTINATION "foo.app/Contents/MacOS")
>>> 
>>> 
>>> I would prefer to not be required to use the .app bundle directory structure at all. I'm not producing a .app. The program is a command line program intended to be run directly from Terminal.app, not a GUI program intended to be launched from Mac OS's Finder. I just want to automatically detect the necessary .dylibs, copy them into the folder that gets zipped up, fix up the dyld paths to make the executable relocatable, and zip up the whole thing.
>>> 
>>> ---
>>> 
>>> Here's the scripts I've got on Windows and which produce the desired products, but which fail on Mac OS.
>>> 
>>> CMakeLists.txt:
>>> 
>>> ...
>>>> 7 add_executable(main main.cpp)
>>> ...
>>>> 10 target_include_directories(main PRIVATE ${somelib_INCLUDE_DIRS})
>>>> 11 target_link_libraries(main PRIVATE ${somelib_LIBRARIES})
>>> ...
>>>> 14 install(TARGETS main DESTINATION ".")
>>>> 15 
>>>> 16 configure_file(
>>>> 17   ${CMAKE_CURRENT_SOURCE_DIR}/FixBundle.cmake.in
>>>> 18   ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake
>>>> 19   @ONLY)
>>>> 20 
>>>> 21 install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake)
>>>> 22 
>>>> 23 set(CPACK_GENERATOR ZIP 7Z TBZ2)
>>>> 24 include(CPack)
>>> 
>>> FixBundle.cmake.in
>>> 
>>>> 1 include(BundleUtilities)
>>>> 2 
>>>> 3 set(bundle "${CMAKE_INSTALL_PREFIX}/main at CMAKE_EXECUTABLE_SUFFIX@")
>>>> 4 
>>>> 5 set(other_libs "")
>>>> 6 set(dirs
>>>> 7   "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@"
>>>> 8   "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@"
>>>> 9 )
>>>> 10 
>>>> 11 fixup_bundle("${bundle}" "${other_libs}" "${dirs}")
>>>> 12 
>>> 
>>> 
>>> -- 
>>> 
>>> 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
>> 
> 



More information about the CMake mailing list