Support generation of working Xcode project for signature purposes on MacOS (#15303)

This commit is contained in:
sfence 2024-11-10 19:06:52 +01:00 committed by GitHub
parent ec7738934b
commit e55ba9c390
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 309 additions and 30 deletions

@ -30,7 +30,7 @@ on:
- '.github/workflows/macos.yml' - '.github/workflows/macos.yml'
jobs: jobs:
build: build-intel-macos:
# use lowest possible macOS running on x86_64 supported by brew to support more users # use lowest possible macOS running on x86_64 supported by brew to support more users
runs-on: macos-13 runs-on: macos-13
steps: steps:
@ -70,3 +70,44 @@ jobs:
with: with:
name: luanti-macos name: luanti-macos
path: ./build/macos/*.zip path: ./build/macos/*.zip
build-arm-macos-xcode:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
source ./util/ci/common.sh
install_macos_deps
# brew jsoncpp do not include libjsoncpp.a, and if installed header conflict caused build failure
brew uninstall jsoncpp
- name: Build with Cmake
run: |
mkdir build
cd build
cmake .. \
-DCMAKE_OSX_DEPLOYMENT_TARGET=14 \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DCMAKE_INSTALL_PREFIX=../build/macos/ \
-DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE \
-DENABLE_SYSTEM_JSONCPP=OFF
cmake --build . -j$(sysctl -n hw.logicalcpu)
make install
- name: Build and Archive with Xcode
run: |
mkdir build_xcode
cd build_xcode
../util/ci/build_xcode.sh
- name: Tests
run: |
mkdir -p "${HOME}/Library/Application Support/minetest/games/"
ln -s "${PWD}/games/devtest" "${HOME}/Library/Application Support/minetest/games/"
./build/macos/luanti.app/Contents/MacOS/luanti --run-unittests
./build_xcode/luanti.xcarchive/Products/Applications/luanti.app/Contents/MacOS/luanti --run-unittests
- name: Diff Resources
run: |
diff -rd ./build/macos/luanti.app/Contents/Resources ./build_xcode/build/Release/luanti.app/Contents/Resources || exit 1
diff -rd ./build/macos/luanti.app/Contents/Resources ./build_xcode/luanti.xcarchive/Products/Applications/luanti.app/Contents/Resources || exit 1

@ -272,7 +272,11 @@ endif()
if(APPLE) if(APPLE)
install(FILES "misc/luanti-icon.icns" DESTINATION "${SHAREDIR}") install(FILES "misc/luanti-icon.icns" DESTINATION "${SHAREDIR}")
install(FILES "misc/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents") install(FILES "${CMAKE_BINARY_DIR}/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents")
endif()
if(CMAKE_GENERATOR STREQUAL "Xcode")
set(client_RESOURCES "${CMAKE_SOURCE_DIR}/misc/luanti-icon.icns")
endif() endif()
# Library pack # Library pack

@ -16,11 +16,13 @@ brew install cmake freetype gettext gmp hiredis jpeg-turbo jsoncpp leveldb libog
Download source (this is the URL to the latest of source repository, which might not work at all times) using Git: Download source (this is the URL to the latest of source repository, which might not work at all times) using Git:
```bash ```bash
git clone --depth 1 https://github.com/minetest/minetest.git git clone --depth 1 https://github.com/minetest/minetest.git luanti
cd minetest cd luanti
``` ```
## Build ## Building for personal usage
### Build
```bash ```bash
mkdir build mkdir build
@ -34,12 +36,65 @@ cmake .. \
make -j$(sysctl -n hw.logicalcpu) make -j$(sysctl -n hw.logicalcpu)
make install make install
# M1 Macs w/ MacOS >= BigSur # Apple Silicon (M1/M2) Macs w/ MacOS >= BigSur signature for local run
codesign --force --deep -s - macos/minetest.app codesign --force --deep -s - --entitlements ../misc/macos/entitlements/debug.entitlements macos/luanti.app
``` ```
## Run If you are using LuaJIT with `MAP_JIT` support use `debug_map_jit.entitlements`.
### Run
``` ```
open ./build/macos/minetest.app open ./build/macos/luanti.app
``` ```
## Building for distribution
### Generate Xcode project
```bash
mkdir build
cd build
cmake .. \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE \
-DFREETYPE_LIBRARY=/path/to/lib/dir/libfreetype.a \
-DGETTEXT_INCLUDE_DIR=/path/to/include/dir \
-DGETTEXT_LIBRARY=/path/to/lib/dir/libintl.a \
-DLUA_LIBRARY=/path/to/lib/dir/libluajit-5.1.a \
-DOGG_LIBRARY=/path/to/lib/dir/libogg.a \
-DVORBIS_LIBRARY=/path/to/lib/dir/libvorbis.a \
-DVORBISFILE_LIBRARY=/path/to/lib/dir/libvorbisfile.a \
-DZSTD_LIBRARY=/path/to/lib/dir/libzstd.a \
-DGMP_LIBRARY=/path/to/lib/dir/libgmp.a \
-DJSON_LIBRARY=/path/to/lib/dir/libjsoncpp.a \
-DENABLE_LEVELDB=OFF \
-DENABLE_POSTGRESQL=OFF \
-DENABLE_REDIS=OFF \
-DJPEG_LIBRARY=/path/to/lib/dir/libjpeg.a \
-DPNG_LIBRARY=/path/to/lib/dir/libpng.a \
-DCMAKE_EXE_LINKER_FLAGS=-lbz2\
-GXcode
```
If you are using LuaJIT with `MAP_JIT` support add `-DXCODE_CODE_SIGN_ENTITLEMENTS=../misc/macos/entitlements/release_map_jit.entitlements`.
*WARNING:* You have to regenerate Xcode project if you switch commit, branch or etc.
### Build and Run
* Open generated Xcode project
* Select scheme `luanti`
* Configure signing Team etc.
* Run Build command
* Open application from `build/build/Debug/` directory or run it from Xcode
### Archive and Run
* Open generated Xcode project
* Select scheme `luanti`
* Configure signing Team etc.
* Run Build command
* Open application archive in finder, go into it, copy application and test it.

@ -313,21 +313,6 @@ add_library(IRRMESHOBJ OBJECT
target_link_libraries(IRRMESHOBJ PUBLIC tiniergltf::tiniergltf) target_link_libraries(IRRMESHOBJ PUBLIC tiniergltf::tiniergltf)
add_library(IRROBJ OBJECT
CBillboardSceneNode.cpp
CCameraSceneNode.cpp
CDummyTransformationSceneNode.cpp
CEmptySceneNode.cpp
CMeshManipulator.cpp
CSceneCollisionManager.cpp
CSceneManager.cpp
CMeshCache.cpp
)
# Make sure IRROBJ gets the transitive include directories for
# tiniergltf from IRRMESHOBJ.
target_link_libraries(IRROBJ PRIVATE IRRMESHOBJ)
set(IRRDRVROBJ set(IRRDRVROBJ
CNullDriver.cpp CNullDriver.cpp
CGLXManager.cpp CGLXManager.cpp
@ -460,14 +445,29 @@ add_library(IRRGUIOBJ OBJECT
# Library # Library
add_library(IrrlichtMt STATIC) # There have to be some sources in IrrlichtMt to workaround Cmake Xcode generator bug
add_library(IrrlichtMt STATIC
CBillboardSceneNode.cpp
CCameraSceneNode.cpp
CDummyTransformationSceneNode.cpp
CEmptySceneNode.cpp
CMeshManipulator.cpp
CSceneCollisionManager.cpp
CSceneManager.cpp
CMeshCache.cpp
)
foreach(object_lib foreach(object_lib
IRRMESHOBJ IRROBJ IRRVIDEOOBJ IRRMESHOBJ IRRVIDEOOBJ
IRRIOOBJ IRROTHEROBJ IRRGUIOBJ) IRRIOOBJ IRROTHEROBJ IRRGUIOBJ)
# Set include directories for object library compilation # Set include directories for object library compilation
target_include_directories(${object_lib} PRIVATE ${link_includes}) target_include_directories(${object_lib} PRIVATE ${link_includes})
# Add objects from object library to main library if(CMAKE_GENERATOR STREQUAL "Xcode")
target_sources(IrrlichtMt PRIVATE $<TARGET_OBJECTS:${object_lib}>) # Workaround for Cmake Xcode project generator
target_link_libraries(IrrlichtMt PRIVATE ${object_lib})
else()
# Add objects from object library to main library
target_sources(IrrlichtMt PRIVATE $<TARGET_OBJECTS:${object_lib}>)
endif()
if(BUILD_WITH_TRACY) if(BUILD_WITH_TRACY)
target_link_libraries(${object_lib} PRIVATE Tracy::TracyClient) target_link_libraries(${object_lib} PRIVATE Tracy::TracyClient)

@ -9,11 +9,15 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>luanti-icon.icns</string> <string>luanti-icon.icns</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>Luanti</string> <string>@PROJECT_NAME_CAPITALIZED@</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Luanti</string> <string>@PROJECT_NAME_CAPITALIZED@</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.luanti.luanti</string> <string>org.luanti.luanti</string>
<key>CFBundleVersion</key>
<string>@VERSION_STRING@</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<false/> <false/>
</dict> </dict>

@ -0,0 +1,10 @@
<?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 version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>

@ -0,0 +1,10 @@
<?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 version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?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 version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?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 version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
</dict>
</plist>

@ -598,6 +598,14 @@ if(PRECOMPILE_HEADERS)
target_precompile_headers(EngineCommon PRIVATE ${PRECOMPILED_HEADERS_LIST}) target_precompile_headers(EngineCommon PRIVATE ${PRECOMPILED_HEADERS_LIST})
endif() endif()
if(APPLE)
# Configure the Info.plist file
configure_file(
"${CMAKE_SOURCE_DIR}/misc/macos/Info.plist.in"
"${CMAKE_BINARY_DIR}/Info.plist"
)
endif()
if(BUILD_CLIENT) if(BUILD_CLIENT)
# client target # client target
if(ANDROID) if(ANDROID)
@ -605,6 +613,47 @@ if(BUILD_CLIENT)
else() else()
add_executable(${PROJECT_NAME}) add_executable(${PROJECT_NAME})
endif() endif()
if(CMAKE_GENERATOR STREQUAL "Xcode")
# File with used entitlements
set(XCODE_CODE_SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/misc/macos/entitlements/release.entitlements" CACHE FILEPATH "Path to entitlements file to be used with Xcode signing")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/build")
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/build")
target_sources(${PROJECT_NAME} PUBLIC ${client_RESOURCES})
add_dependencies(${PROJECT_NAME} translations)
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_BINARY_DIR}/Info.plist"
RESOURCE "${client_RESOURCES}"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "org.luanti.luanti"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES"
XCODE_ATTRIBUTE_INSTALL_PATH "/Applications"
XCODE_ATTRIBUTE_SKIP_INSTALL "NO"
XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS "YES"
XCODE_ATTRIBUTE_CONFIGURATION_BUILD_DIR "$(inherited)"
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${XCODE_CODE_SIGN_ENTITLEMENTS}"
)
# Prinv env variables to file, for debugging purposes
#add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E env bash ${CMAKE_SOURCE_DIR}/util/xcode/capture_env.sh ${CMAKE_BINARY_DIR}/post_env.log
#)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/util/xcode/install_resources.cmake
-DTARGET_DIR=$<TARGET_FILE_DIR:${PROJECT_NAME}>
-DBINARY_DIR=${CMAKE_BINARY_DIR}
-DPROJECT_NAME=${PROJECT_NAME}
COMMENT "Checking INSTALL_ROOT and copying resources"
)
endif()
list(SORT client_SRCS) list(SORT client_SRCS)
target_sources(${PROJECT_NAME} PRIVATE target_sources(${PROJECT_NAME} PRIVATE
$<TARGET_OBJECTS:EngineCommon> $<TARGET_OBJECTS:EngineCommon>

24
util/ci/build_xcode.sh Executable file

@ -0,0 +1,24 @@
#!/bin/bash -e
cmake .. \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE \
-DFREETYPE_LIBRARY=/opt/homebrew/lib/libfreetype.a \
-DGETTEXT_INCLUDE_DIR=/path/to/include/dir \
-DGETTEXT_LIBRARY=/opt/homebrew/lib/libintl.a \
-DLUA_LIBRARY=/opt/homebrew/lib/libluajit-5.1.a \
-DOGG_LIBRARY=/opt/homebrew/lib/libogg.a \
-DVORBIS_LIBRARY=/opt/homebrew/lib/libvorbis.a \
-DVORBISFILE_LIBRARY=/opt/homebrew/lib/libvorbisfile.a \
-DZSTD_LIBRARY=/opt/homebrew/lib/libzstd.a \
-DGMP_LIBRARY=/opt/homebrew/lib/libgmp.a \
-DENABLE_SYSTEM_JSONCPP=OFF \
-DENABLE_LEVELDB=OFF \
-DENABLE_POSTGRESQL=OFF \
-DENABLE_REDIS=OFF \
-DJPEG_LIBRARY=/opt/homebrew/lib/libjpeg.a \
-DPNG_LIBRARY=/opt/homebrew/lib/libpng.a \
-DCMAKE_EXE_LINKER_FLAGS=-lbz2\
-GXcode
xcodebuild -project luanti.xcodeproj -scheme luanti -configuration Release build
xcodebuild -project luanti.xcodeproj -scheme luanti -archivePath ./luanti.xcarchive archive

@ -0,0 +1,3 @@
#!/bin/bash
env > $1

@ -0,0 +1,63 @@
# This is only one working solution I found to be working for normal and Archive builds under Xcode 15.4
# I expect higger sensitivity to Xcode version.
if(DEFINED ENV{INSTALL_ROOT} AND EXISTS "$ENV{INSTALL_ROOT}")
set(RESOURCES_DIR "$ENV{INSTALL_ROOT}/Applications/$ENV{PRODUCT_NAME}.app/Contents/Resources")
else()
set(RESOURCES_DIR "$ENV{TARGET_BUILD_DIR}/$ENV{UNLOCALIZED_RESOURCES_FOLDER_PATH}")
endif()
# Write debug information to a file
#file(WRITE "$ENV{PROJECT_FILE_PATH}/../debug_output.txt" "INSTALL_ROOT: $ENV{INSTALL_ROOT}\n")
#file(APPEND "$ENV{PROJECT_FILE_PATH}/../debug_output.txt" "RESOURCES_DIR: ${RESOURCES_DIR}\n")
#file(APPEND "$ENV{PROJECT_FILE_PATH}/../debug_output.txt" "TARGET_BUILD_DIR: $ENV{TARGET_BUILD_DIR}\n")
#file(APPEND "$ENV{PROJECT_FILE_PATH}/../debug_output.txt" "BUILT_PRODUCTS_DIR: $ENV{BUILT_PRODUCTS_DIR}\n")
#file(APPEND "$ENV{PROJECT_FILE_PATH}/../debug_output.txt" "SOURCE_ROOT: $ENV{SOURCE_ROOT}\n")
#file(APPEND "$ENV{PROJECT_FILE_PATH}/../debug_output.txt" "PRODUCT_NAME: $ENV{PRODUCT_NAME}\n")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$ENV{SOURCE_ROOT}/builtin"
"${RESOURCES_DIR}/builtin"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$ENV{SOURCE_ROOT}/client/shaders"
"${RESOURCES_DIR}/client/shaders"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$ENV{SOURCE_ROOT}/fonts"
"${RESOURCES_DIR}/fonts"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$ENV{PROJECT_FILE_PATH}/../locale"
"${RESOURCES_DIR}/locale"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory
"${RESOURCES_DIR}/$ENV{PRODUCT_NAME}"
)
set(RESOURCE_LUANTI_FILES
"$ENV{SOURCE_ROOT}/README.md"
"$ENV{SOURCE_ROOT}/doc/client_lua_api.md"
"$ENV{SOURCE_ROOT}/doc/lua_api.md"
"$ENV{SOURCE_ROOT}/doc/menu_lua_api.md"
"$ENV{SOURCE_ROOT}/minetest.conf.example"
"$ENV{SOURCE_ROOT}/doc/texture_packs.md"
"$ENV{SOURCE_ROOT}/doc/world_format.md"
)
foreach (file ${RESOURCE_LUANTI_FILES})
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy
"${file}"
"${RESOURCES_DIR}/$ENV{PRODUCT_NAME}/"
)
endforeach()
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$ENV{SOURCE_ROOT}/textures/base/pack"
"${RESOURCES_DIR}/textures/base/pack"
)