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
)
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

Reply via email to