[CMake] CMAKE_OSX_SYSROOT icw iOS fat binaries (iPhone + iPhoneSimulator)
Erik van Nooijen
Eric.vanNooijen at tomtom.com
Mon Nov 19 06:18:57 EST 2018
With CMake it is possible to build for fat binaries for iOS without XCode. Fat binaries meaning containing all the architectures for iPhone and iPhoneSimulator.
However, when building frameworks, CMake builds it with the MacOSX layout, including 'Version' directory and symlinks etc. This is wrong when building for iOS.
The reason is that CMake determines bundle layout based on CMAKE_OSX_SYSROOT, but this cannot be set correctly in this situation, as it allows only one directory to be set, and we'd need two (iPhone and iPhoneSimulator). In short:
* not setting CMAKE_OSX_SYSROOT results in MacOSX framework/bundle layouts
* setting CMAKE_OSX_SYSROOT to a single sysroot gives error for the other architecture(s)
ld: dynamic main executables must link with libSystem.dylib for architecture i386
* setting CMAKE_OSX_SYSROOT to multiple sysroots gives error for incorrect paths
Ignoring CMAKE_OSX_SYSROOT value:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.1.sdk;/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.1.sdk
because the directory does not exist.
Please find below an example CMakeLists.txt to test/verify this. The behaviour can be switched on and off with the MAKE_FAT variable.
What is the correct way to get fat binaries in the correct iOS layout in such a case?
cmake_minimum_required(VERSION 3.13)
project(iOSFatBinaries)
set(MAKE_FAT TRUE)
execute_process(COMMAND xcodebuild -version -sdk iphoneos Path COMMAND perl -ne "chomp;print;exit;" OUTPUT_VARIABLE SDK_IPHONE_ROOT)
execute_process(COMMAND xcodebuild -version -sdk iphonesimulator Path COMMAND perl -ne "chomp;print;exit;" OUTPUT_VARIABLE SDK_IPHONE_SIMULATOR_ROOT)
# CMAKE_OSX_ARCHITECTURES
if(MAKE_FAT)
set(CMAKE_OSX_ARCHITECTURES "armv7;armv7s;arm64;i386;x86_64" CACHE INTERNAL "Set supported OSX architectures")
else()
set(CMAKE_OSX_ARCHITECTURES "armv7;armv7s;arm64" CACHE INTERNAL "Set supported OSX architectures")
endif()
# CMAKE_C_FLAGS and CMAKE_CXX_FLAGS
if(MAKE_FAT)
set(SYSROOT_FLAGS " -arch armv7 -Xarch_armv7 \"-isysroot${SDK_IPHONE_ROOT}\"")
set(SYSROOT_FLAGS "${SYSROOT_FLAGS} -arch armv7s -Xarch_armv7s \"-isysroot${SDK_IPHONE_ROOT}\"")
set(SYSROOT_FLAGS "${SYSROOT_FLAGS} -arch arm64 -Xarch_arm64 \"-isysroot${SDK_IPHONE_ROOT}\"")
set(SYSROOT_FLAGS "${SYSROOT_FLAGS} -arch i386 -Xarch_i386 \"-isysroot${SDK_IPHONE_SIMULATOR_ROOT}\"")
set(SYSROOT_FLAGS "${SYSROOT_FLAGS} -arch x86_64 -Xarch_x86_64 \"-isysroot${SDK_IPHONE_SIMULATOR_ROOT}\"")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SYSROOT_FLAGS}" CACHE INTERNAL "CMake C Compiler Flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SYSROOT_FLAGS}" CACHE INTERNAL "CMake CXX Compiler Flags")
else()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch armv7 -arch armv7s -arch arm64")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch armv7 -arch armv7s -arch arm64")
endif()
# CMAKE_CXX_FLAGS
if(MAKE_FAT)
set(CMAKE_OSX_SYSROOT "" CACHE INTERNAL "sysroot" FORCE)
else()
set(CMAKE_OSX_SYSROOT ${SDK_IPHONE_ROOT} CACHE INTERNAL "sysroot" FORCE)
endif()
add_library(${PROJECT_NAME} SHARED
lib.h
lib.cpp
)
# Framework properties
set_target_properties(${PROJECT_NAME} PROPERTIES
FRAMEWORK TRUE
FORCE_IOS_BUNDLE_LAYOUT TRUE
MACOSX_FRAMEWORK_IDENTIFIER ${PROJECT_NAME}
MACOSX_FRAMEWORK_BUNDLE_VERSION 1.0
MACOSX_FRAMEWORK_SHORT_VERSION_STRING 1.0
MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
PUBLIC_HEADER lib.h
)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20181119/32aa6c02/attachment-0001.html>
More information about the CMake
mailing list