Creating a macOS App Bundle from several executable and Framework

I’m building an app that needs several executables and frameworks. I can built everything just as an executable and that’s fine, but I’m confused about how to get CMake to build a MACOSX_BUNDLE for me. I can see that I can use MACOSX_BUNDLE to create an app bundle, but that doesn’t do everything I want.

So, I have two executable, exeA and exeB and both needs to be placed in MacOS folder. The exeA uses exeB and the exeB uses a Framework that it is liked to. Basically, I’m wondering if there is a way to get all these into a bundle using CMake, that I have something like this:

App.app
    - Contents
       - MacOS
           - exeA
           - exeB
       - Frameworks
           - my.Framework
       - Resources
           - Translation
           - Docs
           - etc.

I can achieve some of this using the set_target_properties but I don’t know how to get the second executable, exeB into the mix without manually moving it there. The same for the Framework.

Should I do all these with the install command?

After some reading, and digging into the Professional CMake book (thanks @craig.scott), I now know how to get my Resources into the Bundle, and I think I linked my Framework correctly as well, but I cannot get it to be copied fully into the Framework folder, and I still have some issues with the executables.

For the resources, if anyone wonder, I’m using this snippet to keep the folder structure.

file(GLOB_RECURSE BUNDLE_RESOURCES "${CMAKE_SOURCE_DIR}/Resources/*")

# This is a handy little for-loop from here, https://stackoverflow.com/a/66401708/1141307,
# which keeps all the resource files into the Resources folder while
# keeping their relative path. So, I don't have to group them manually.
# Individually set the file's path properties.
foreach (FILE ${BUNDLE_RESOURCES})
    # Get the relative path from the Resources to the particular file.
    file(RELATIVE_PATH NEW_FILE "${CMAKE_SOURCE_DIR}/Resources" ${FILE})

    # Get the relative path to the file.
    get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY)

    # Set it's location inside the app package (under Resources).
    set_property(SOURCE ${FILE} 
                 PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}")

    # Optional: Add the file to the 'Resources' folder group in Xcode.
    #           This also preserves folder structure.
    source_group("Resources/${NEW_FILE_PATH}" FILES "${FILE}")
endforeach ()

and I’m attempting to link the Framework like this, but for some reason, the Contents/Frameworks/My.framework will end up being empty. This is an external framework and CMake didn’t build it. I just leave it at the source directory for now.

set_target_properties(JASP PROPERTIES
    XCODE_EMBED_FRAMEWORKS  ${CMAKE_SOURCE_DIR}/My.framework
)

set_source_files_properties(
    ${CMAKE_SOURCE_DIR}/My.framework PROPERTIES
    MACOSX_PACKAGE_LOCATION Frameworks)

also, I tried to copy my other executable into the MacOS folder like this, and I don’t get anything for some reason. I’m not sure if I should use the INSTALL command or not. I think I shouldn’t because then Xcode will be confused during the build probably.

set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Desktop/JASPEngine
              PROPERTY MACOSX_PACKAGE_LOCATION MacOS)

Any help is appriciated! :slight_smile: