Le 08.08.17 à 14:08, Raffi Enficiaud a écrit :
Hi CMake ML,I am quite new to the topic of making toolchain files. However I need to build a not so trivial application for iOS and I want to do it with CMake, and if possible walk toward an official support of iOS in CMake. I have looked a bit to the Android toolchains, and I have to say I found those quite complicated as a first reading :) The target application I am building uses Qt and Boost. So far, I have managed to have an IOS toolchain file that is generating a looking good XCode project, that I can compile properly (up until signing). [snip]
Hi there,Following the thread, I would like to suggest a toolchain file for iOS, attached to this post.
I used this to compile a not too small project using Qt, Boost, LSL and some other fancy dependencies, and the project runs at least on the simulator (waiting for a real device).
The way it works:- we need different build trees for the simulator and for a real device (not same arch nor base SDK). Changing this is way too difficult and the workaround of having different build trees, although not very "elegant", just work
- for the simulator cmake -G Xcode \ -DCMAKE_TOOLCHAIN_FILE=ios_toolchain.cmake \ -DIOS_PLATFORM=SIMULATOR \ ../some-path - for a real device cmake -G Xcode \ -DCMAKE_TOOLCHAIN_FILE=ios_toolchain.cmake \ -DIOS_PLATFORM=OS \ ../some-path- for the device, we need a real certificate for signing that can be set directly from within XCode or by setting `XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=YES` and the companion variables to the appropriate values
Next steps:* I can set up a machine for running the tests as I am doing for the Matlab package. Those tests would be for the moment compilation tests. I would be happy to discuss on how to do real "runtime" tests. * I can proceed further with the documentation of course if people are happy with this toolchain file * I can add other SDKs like watchOS and such, but before proceeding further I would prefer to have a feature complete implementation for iOS device+simulator (I believe this is the most demanded). * I can check how to tweak CROSSCOMPILING_EMULATOR to run things on an emulator in case we are on the simulator. I believe add_test should be disabled when compiling for a real device * I would like to know if there is any direction in indicating the bundles structures, as those are different for iOS and macOS. Right now I am using a switch like this
if(IOS) set(OSX_BUNDLE_RELATIVE_PATH ".") else() set(OSX_BUNDLE_RELATIVE_PATH "../..") endif() add_custom_command( TARGET myproj POST_BUILDCOMMAND ${CMAKE_COMMAND} -DAPPFOLDER=$<TARGET_FILE_DIR:myproj>/${OSX_BUNDLE_RELATIVE_PATH} "-DSOMEPARAMS=${BOOST_LIB_PATH}"
-P ${CMAKE_SOURCE_DIR}/cmake/osx_bundle.cmake
)
to get the path to the root folder of the bundle. I do not know if there
is anything like this in CMake already (the BundleUtilities I believe
has relative paths written in hard).
Thanks! Raffi
# cmake -G Xcode \ # -DCMAKE_TOOLCHAIN_FILE=./ios_toolchain.cmake \ # -DCMAKE_PREFIX_PATH=~/Qt5.9.1/5.9.1/ios/ \ # -DBOOST_ROOT=~/Code/SoftwareWorkshop/sw_thirdparties/osx/boost_1_63_0 # -DBoost_COMPILER=-xgcc42 ../source # * `IOS`: indicates that the build is being performed for iOS (generic device or simulator) # * `IOS_PLATFORM`: indicates the platform to compile for. This can be the genuine operating system (`OS`) or the simulator (`SIMULATOR`) # * `IOS_ARCH`: the architecture to compile. The default is dependant on the `IOS_PLATFORM`: # * `armv7;arm64` for the `IOS` # * `i386;x86_64` for the `SIMULATOR` # # Other variables # # * `CMAKE_IOS_SDK_ROOT`: indicates the name of an SDK to choose, defaults to the "most recent" SDK # # By default code signing is `OFF`, but should be activated per target in order to have the compilation # possible for iOS device (Xcode defaults to some ad-hox signing otherwise). This can be done # through the target properties `XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED` # TODO # - documentation # - detects automatically sdks and target systems from XCode, and lists the sysroots # - this is for IOS only, not watchOS or anything else # - indicate the bundle structure for this target system (different than from macOS) # - indicate how to run tests maybe through `CROSSCOMPILING_EMULATOR` # - fix the tests # - find other libraries that clang/clang++ ? # some relevant doc/resources # https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Using/using.html#//apple_ref/doc/uid/20002000-SW6 # for running simulator # https://stackoverflow.com/questions/26031601/xcode-6-launch-simulator-from-command-line # can be consumed with # https://cmake.org/cmake/help/v3.8/prop_tgt/CROSSCOMPILING_EMULATOR.html # Raffi: automated code signing # public.kitware.com/pipermail/cmake/2016.../064602.html # set_target_properties(app PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "PROPER IDENTIFIER") # listing all signing identities # security find-identity -v -p codesigning # signing a binary # codesign -s my-signing-identity -f ./md5 # signing code manually # https://developer.apple.com/library/content/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html # examining a .a # lipo -info boost_1_63_0_ios/lib/libboost_filesystem.a set(CMAKE_SYSTEM_NAME Darwin) set(CMAKE_SYSTEM_VERSION 1) set(UNIX True) set(APPLE True) set(IOS True) # if(NOT DEFINED IOS_PLATFORM) set(IOS_PLATFORM "OS") endif() # left as an example on how to list things from command line utilities # to be integrated if(FALSE) execute_process( COMMAND xcodebuild -sdk -version RESULT_VARIABLE XCODE_SYSROOT_LISTING_RES OUTPUT_VARIABLE XCODE_SYSROOT_LISTING ERROR_VARIABLE XCODE_SYSROOT_LISTING_ERROR ) if(NOT "${XCODE_SYSROOT_LISTING_RES}" STREQUAL "0") message(FATAL_ERROR "Cannot list SDKs from xcodebuild. Please make sure XCode is properly installed") endif() string(REGEX MATCHALL "Path:[ ]*([a-zA-Z0-9/\\. ]+)" VAR_MATCH "${XCODE_SYSROOT_LISTING}" ) list(REMOVE_DUPLICATES VAR_MATCH) message("${VAR_MATCH}") endif() # for each SDK, showing the version: # xcrun --sdk iphoneos --show-sdk-version # # Detect the current XCode # if(NOT DEFINED XCODE_ROOT_PATH) execute_process( COMMAND xcode-select -print-path RESULT_VARIABLE XCODE_COMPILER_PRINT_PATH_RES OUTPUT_VARIABLE XCODE_COMPILER_PRINT_PATH ERROR_VARIABLE XCODE_COMPILER_PRINT_PATH_ERROR ) # Raffi : check errors set(_suffix_app ".app") string(FIND "${XCODE_COMPILER_PRINT_PATH}" "${_suffix_app}/" VAR_LOCATION_APP) string(SUBSTRING "${XCODE_COMPILER_PRINT_PATH}" 0 "${VAR_LOCATION_APP}" XCODE_ROOT_PATH) set(XCODE_ROOT_PATH "${XCODE_ROOT_PATH}${_suffix_app}" CACHE STRING "XCode ROOT folder" FORCE) endif() # # Check the platform selection and setup for developer root if(IOS_PLATFORM STREQUAL "OS") set(IOS_PLATFORM_LOCATION "iPhoneOS.platform") set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos") # This causes the installers to properly locate the output libraries elseif(IOS_PLATFORM STREQUAL "SIMULATOR") set(IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") else() message(FATAL_ERROR "Unsupported IOS_PLATFORM value selected. Please choose OS or SIMULATOR") endif() # Indicate cross compilation: we suppose that we never perform compilation direclty # on a device set(CMAKE_CROSSCOMPILING TRUE) # # looking for the compilers # Check how to do it consistently with XCODE_ROOT_PATH if(NOT DEFINED XCODE_COMPILER_CLANG) execute_process( COMMAND xcodebuild -find-executable clang RESULT_VARIABLE XCODE_COMPILER_CLANG_RES OUTPUT_VARIABLE XCODE_COMPILER_CLANG ERROR_VARIABLE XCODE_COMPILER_CLANG_ERROR ) if(NOT "${XCODE_COMPILER_CLANG_RES}" STREQUAL "0") message(FATAL_ERROR "IOSToolchain: 'clang' compiler cannot be found") endif() set(XCODE_COMPILER_CLANG "${XCODE_COMPILER_CLANG}" CACHE STRING "XCode clang compiler" FORCE) endif() if(NOT DEFINED XCODE_COMPILER_CLANGPP) execute_process( COMMAND xcodebuild -find-executable clang++ RESULT_VARIABLE XCODE_COMPILER_CLANGPP_RES OUTPUT_VARIABLE XCODE_COMPILER_CLANGPP ERROR_VARIABLE XCODE_COMPILER_CLANGPP_ERROR ) if(NOT "${XCODE_COMPILER_CLANGPP_RES}" STREQUAL "0") message(FATAL_ERROR "IOSToolchain: 'clang++' compiler cannot be found") endif() set(XCODE_COMPILER_CLANGPP "${XCODE_COMPILER_CLANGPP}" CACHE STRING "XCode clang++ compiler" FORCE) endif() set(CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment target for iOS" FORCE) set(CMAKE_IOS_DEVELOPER_ROOT "${XCODE_ROOT_PATH}/Contents/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer") # Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT if (NOT DEFINED CMAKE_IOS_SDK_ROOT) file(GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*") if(_CMAKE_IOS_SDKS) list(SORT _CMAKE_IOS_SDKS) list(REVERSE _CMAKE_IOS_SDKS) list(GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT) else() message(FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.") endif() message(STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}") endif() set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK") # this variable is used all over the places in CMake, we override it with the # iOS SDK root found set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") # # set the architecture for iOS # if(NOT DEFINED IOS_ARCH) if (IOS_PLATFORM STREQUAL "OS") set(CMAKE_SYSTEM_PROCESSOR arm) set(IOS_ARCH armv7 arm64) elseif(IOS_PLATFORM STREQUAL "SIMULATOR") set(CMAKE_SYSTEM_PROCESSOR x86_64) set(IOS_ARCH i386 x86_64) endif() endif() set(CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS") # Set the find root to the iOS developer roots and to user defined paths set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root" ) # set up the default search directories for frameworks set (CMAKE_SYSTEM_FRAMEWORK_PATH ${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks ${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks ) # visibility flags set (CMAKE_CXX_FLAGS_INIT "-fvisibility=hidden -fvisibility-inlines-hidden") # from https://public.kitware.com/Bug/view.php?id=15329 set(CMAKE_MACOSX_BUNDLE YES) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") if(CMAKE_OSX_SYSROOT) if(NOT IS_DIRECTORY "${CMAKE_OSX_SYSROOT}") message(FATAL_ERROR "iOS: The system root directory needed for the selected iOS version and architecture does not exist:\n" " ${CMAKE_OSX_SYSROOT}\n" ) endif() else() message(FATAL_ERROR "iOS: No CMAKE_OSX_SYSROOT was selected." ) endif() set(CMAKE_BUILD_TYPE_INIT Debug)
-- 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: http://public.kitware.com/mailman/listinfo/cmake-developers
