Skip to content

Instantly share code, notes, and snippets.

@SamuelMarks
Created September 18, 2022 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SamuelMarks/b5691d65341770652df2f277b8c45df5 to your computer and use it in GitHub Desktop.
Save SamuelMarks/b5691d65341770652df2f277b8c45df5 to your computer and use it in GitHub Desktop.
CMake hacks to create a Bundle for macOS
if (BUILD_APPLE_BUNDLE)
set(EXEC_NAME "MyUI")
else ()
get_filename_component(EXEC_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
string(APPEND EXEC_NAME "-${PROJECT_VERSION}")
endif ()
set(Source_Files "main.c")
source_group("Source Files" FILES "${Source_Files}")
add_executable("${EXEC_NAME}" "${Source_Files}")
if (MSVC)
set_property(TARGET "${EXEC_NAME}" APPEND_STRING PROPERTY LINK_FLAGS " /NODEFAULTLIB:MSVCRTD")
endif (MSVC)
target_link_libraries(
"${EXEC_NAME}"
PRIVATE
"${PROJECT_NAME}_compiler_flags"
"${PROJECT_NAME}_lib"
)
set_target_properties(
"${EXEC_NAME}"
PROPERTIES
LINKER_LANGUAGE
C
)
# install rules
include(GNUInstallDirs)
set(RESOURCE_FILES "")
foreach (_dir "icons" "images")
file(GLOB ls LIST_DIRECTORIES false "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/${_dir}/*")
if (BUILD_APPLE_BUNDLE)
foreach (filename ${ls})
list(APPEND RESOURCE_FILES "${filename}")
set_source_files_properties("${filename}" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
endforeach (filename ${ls})
# For debugging before `cmake --install` | `cpack`
file(COPY "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/${_dir}"
DESTINATION "${CMAKE_BINARY_DIR}/${EXEC_NAME}.app/Contents/Resources")
# For `cmake --install` | `cpack`
install(DIRECTORY "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/${_dir}"
DESTINATION "${EXEC_NAME}.app")
else ()
# For debugging before `cmake --install` | `cpack`
file(COPY "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/${_dir}"
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}")
# For `cmake --install` | `cpack`
install(DIRECTORY "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/${_dir}"
DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/${_dir}")
endif (BUILD_APPLE_BUNDLE)
endforeach (_dir "icons" "images")
if (BUILD_APPLE_BUNDLE)
target_compile_options("${EXEC_NAME}" PRIVATE -fPIC -Wpartial-availability -Wno-inconsistent-missing-override -rdynamic)
set_property(TARGET "${EXEC_NAME}" APPEND_STRING PROPERTY LINK_FLAGS "-fPIC -rdynamic")
list(APPEND RESOURCE_FILES "${BUNDLE_ICON}")
# set_target_properties("${EXEC_NAME}" PROPERTIES MACOSX_BUNDLE_ICON_FILE "${BUNDLE_ICON}")
file(COPY "${BUNDLE_ICON}" #${RESOURCE_FILES}
DESTINATION "${CMAKE_BINARY_DIR}/${EXEC_NAME}.app/Contents/Resources")
install(DIRECTORY "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/${_dir}"
DESTINATION "${EXEC_NAME}.app")
set_source_files_properties("${BUNDLE_ICON}" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
foreach (res ${RESOURCE_FILES})
set_source_files_properties("${res}" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
endforeach (res ${RESOURCE_FILES})
target_sources("${EXEC_NAME}" PRIVATE ${MAC_RESOURCE_FILES})
set_target_properties(
"${EXEC_NAME}"
PROPERTIES
MACOSX_BUNDLE_NAME "${EXEC_NAME}"
MACOSX_BUNDLE_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_GUI_IDENTIFIER "org.${EXEC_NAME}.gui"
MACOSX_BUNDLE_ICON_FILE "Icon.icns"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/cmake/Info.plist.in"
MACOSX_BUNDLE "TRUE"
# MACHO_COMPATIBILITY_VERSION "12.0.0"
RESOURCE "${RESOURCE_FILES}"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED NO
XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf
XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN YES
XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME NO
)
# install(TARGETS "${EXEC_NAME}"# "${PROJECT_NAME}_lib"
# # TYPE "RUNTIME"
# RUNTIME DESTINATION "${EXEC_NAME}.app"
# LIBRARY DESTINATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
# ARCHIVE DESTINATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
# BUNDLE DESTINATION "${EXEC_NAME}.app"
# COMPONENT "${PROJECT_NAME}")
install(DIRECTORY "${CMAKE_BINARY_DIR}/${EXEC_NAME}.app" DESTINATION .)
# install(CODE "include(BundleUtilities)"
# "fixup_bundle(\"${EXEC_NAME}\" \"\" \"${RESOURCE_FILES}\")"
# "include(CopyDependencies)"
# "copy_dependencies(\"\${EXEC_NAME}\")"
# COMPONENT "Runtime")
add_custom_command(
TARGET "${EXEC_NAME}" POST_BUILD
COMMAND install_name_tool
-rpath "${CMAKE_BINARY_DIR}/${EXEC_NAME}.app/Contents/PlugIns" '@executable_path/../PlugIns'
"${CMAKE_BINARY_DIR}/${EXEC_NAME}.app/Contents/MacOS/${EXEC_NAME}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Replace library search path from absolute to relative"
)
else ()
install(TARGETS "${EXEC_NAME}" "${PROJECT_NAME}_lib"
# TYPE "RUNTIME"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}/static"
BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}/${EXEC_NAME}.app"
COMPONENT "${PROJECT_NAME}")
endif (BUILD_APPLE_BUNDLE)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist>
<dict>
<key>CFBundleExecutable</key>
<string>myui</string>
<key>CFBundleIconFile</key>
<string>@MACOSX_BUNDLE_ICON_FILE@</string>
<key>CFBundleIdentifier</key>
<string>org.my-ui.gui</string>
<key>CFBundleName</key>
<string>my-ui</string>
<key>CFBundleDisplayName</key>
<string>Archimedes</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>@GUI_VERSION@</string>
<key>CFBundleVersion</key>
<string>@GUI_VERSION@</string>
<key>NSHumanReadableCopyright</key>
<string>Open MyUI</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment