c++macoscmakebundle

How to add resources to MacOS Bundle in CMake


Currently I add resources like this:

cmake_minimum_required(VERSION 3.26)
project(Example VERSION 1.0 LANGUAGES CXX C)

set(SRC
    src/main.cpp
)
set(SHADERS
    shaders/example.frag
)
set(MODELS
    models/cube.obj
)
add_executable(${PROJECT_NAME}
    ${SRC}
    ${SHADERS}
    ${MODELS}
)

if(APPLE)
    # Bundling macOS application
    set_target_properties(${PROJECT_NAME} PROPERTIES
        BUNDLE True
        MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}
        MACOSX_BUNDLE_BUNDLE_VERSION ${CMAKE_PROJECT_VERSION}
        MACOSX_BUNDLE_GUI_IDENTIFIER com.example.${PROJECT_NAME}
        MACOSX_BUNDLE_ICON_FILE AppIcon
        MACOSX_BUNDLE_SHORT_VERSION_STRING ${CMAKE_PROJECT_VERSION}
    )
    set_source_files_properties(${SHADERS}
        PROPERTIES
        MACOSX_PACKAGE_LOCATION "Resources/shaders"
    )
    set_source_files_properties(${MODELS}
        PROPERTIES
        MACOSX_PACKAGE_LOCATION "Resources/models"
    )
    install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .)
endif()

I understand that add_executable is getting a bit abused in here but even the official CMake example https://cmake.org/cmake/help/latest/prop_tgt/RESOURCE.html adds resource files like that and otherwise my resource files won't get copied into my .app folder.

With my shader files this works flawlessly though but I get a problem when adding models. Then CMake fails with following error: [build] ld: unknown file type in '.../models/cube.obj'

I understand that this occurs because add_executable does nothing else than passing the files to the compiler and the compiler probably doesn't like the .objextension.

My current solution is to simply rename my models, for example to models/cube.model but this is very unsatisfactory, is there another way to add resources that is more elegant? Thanks in advance


Solution

  • Was solved here: https://discourse.cmake.org/t/how-to-add-resources-to-macos-bundle/

    The solution was to mark the resource files as HEADER_FILE_ONLY