Re: [cmake-developers] iOS: direction to official support and questions
On Thu, Sep 28, 2017 at 7:40 AM, Brad Kingwrote: > On 09/27/2017 08:18 AM, Raffi Enficiaud wrote: > > For cross-compiling a project on iOS or iOS simulator, and since those 2 > > platforms are still Darwin, I believe that: > > > > * from a user perspective: > >* CMAKE_SYSTEM_NAME should be set to "Darwin" > >* CMAKE_SYSTEM_VERSION should be set to iOS or iOS-simulator, > > possibly with a version (like "Mac OSX 10.2" in Darwin.cmake) > > Although macOS is based on Darwin, it has historically been a mistake > to make CMAKE_SYSTEM_NAME "Darwin". macOS and iOS are different > enough that they each should have their own platform names/modules. > Also, CMAKE_SYSTEM_VERSION should always be a number. > > > However, I just notice the existence of > > "Modules/Platform/Darwin-Initialize.cmake" that is setting several > > variables. When is this file sourced? should be before > > "Modules/Platform/Darwin.cmake" but I failed to see from where. > > See comments here: > > https://gitlab.kitware.com/cmake/cmake/blob/v3.9.3/ > Source/cmGlobalGenerator.cxx#L333-372 > > for how all those files are loaded. `iOS*.cmake` modules would be > appropriate for first-class iOS support. Ideally it should work > with just `-DCMAKE_SYSTEM_NAME=iOS` without a full toolchain file, > if that is possible. > > > I see several problems with this file if I were to make it iOS aware. > > For instance it contains variables that are checking for the version, > > but based only on the macOS scheme. > > That's why CMAKE_SYSTEM_NAME should be distinct so we can use a totally > separate set of modules. I think that solves most of the other problems > you raised. > (Starting on a tangent, coming back to the above at the end). Note also that for iOS builds, you don't really want to go fiddling with the CMAKE_FIND_ROOT_PATH_MODE_... variables, either in toolchain files or in platform support files that come with CMake. You see this a lot in toolchain examples online, but that's not really compatible with the way Xcode allows you to switch between device and simulator builds. There's not really any 100% satisfactory solution to this in CMake at the moment, as Eric Wing has summarised rather well in a few recent emails to this list. As a starting point, I'd recommend only trying to set the minimal things in iOS platform files which give a successful build. The handling of find_...() command search paths falls outside of that, in my view. FWIW, I've been experimenting with this area quite a bit lately after it became a topic of discussion on this list, in the issue tracker and in merge requests. At the moment, a minimal toolchain file for iOS which gets you about as far as you can go seems to be something like this: set(CMAKE_MACOSX_BUNDLE YES) if(NOT CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED NO) endif() set(CMAKE_OSX_SYSROOT iphoneos) All but the last line should ideally be unnecessary, but that's the current state of things at least. The above setting of CMAKE_OSX_SYSROOT works because Xcode sees the SDK as iphoneos but recognises that there's an associated simulator configuration. You can then switch the target platform (device or simulator) at build time without re-running CMake. This is highly desirable for iOS devs, so it raises the question of how to not break that if we make CMAKE_SYSTEM_NAME rather than Darwin + CMAKE_OSX_SYSROOT as the primary way to set up for iOS. Also keep in mind that, while most projects will probably just be happy to use the latest installed SDK by default, it's technically possible to specify a specific SDK version with an appropriate value in CMAKE_OSX_SYSROOT (e.g. iphoneos9.3, or something like that, can't exactly recall off the top of my head). If CMAKE_SYSTEM_NAME is taught to recognise iOS as distinct from Darwin, we'd need to be very careful not to break existing projects that assume the (fragile but still workable for some projects) method above. -- Craig Scott Melbourne, Australia https://crascit.com -- 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
Re: [cmake-developers] iOS: direction to official support and questions
On 09/27/2017 08:18 AM, Raffi Enficiaud wrote: > For cross-compiling a project on iOS or iOS simulator, and since those 2 > platforms are still Darwin, I believe that: > > * from a user perspective: >* CMAKE_SYSTEM_NAME should be set to "Darwin" >* CMAKE_SYSTEM_VERSION should be set to iOS or iOS-simulator, > possibly with a version (like "Mac OSX 10.2" in Darwin.cmake) Although macOS is based on Darwin, it has historically been a mistake to make CMAKE_SYSTEM_NAME "Darwin". macOS and iOS are different enough that they each should have their own platform names/modules. Also, CMAKE_SYSTEM_VERSION should always be a number. > However, I just notice the existence of > "Modules/Platform/Darwin-Initialize.cmake" that is setting several > variables. When is this file sourced? should be before > "Modules/Platform/Darwin.cmake" but I failed to see from where. See comments here: https://gitlab.kitware.com/cmake/cmake/blob/v3.9.3/Source/cmGlobalGenerator.cxx#L333-372 for how all those files are loaded. `iOS*.cmake` modules would be appropriate for first-class iOS support. Ideally it should work with just `-DCMAKE_SYSTEM_NAME=iOS` without a full toolchain file, if that is possible. > I see several problems with this file if I were to make it iOS aware. > For instance it contains variables that are checking for the version, > but based only on the macOS scheme. That's why CMAKE_SYSTEM_NAME should be distinct so we can use a totally separate set of modules. I think that solves most of the other problems you raised. > PS: how should we proceed with the developments? Having a fork on Gitlab > based on master and start integrating from there would be ok? Do you > need a build machine first? Yes, this should be integrated through a fork and merge request. For tests, take a look at how the `Tests/RunCMake/Android` test works. We should be able to turn on iOS support tests on macOS builds on hosts that have iOS development infrastructure installed. -Brad -- 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
Re: [cmake-developers] iOS: direction to official support and questions
Le 27.09.17 à 12:34, Brad King a écrit : On 09/26/2017 05:05 PM, Raffi Enficiaud wrote: Is it possible to source the default setup and to override some parts when a toolchain is given on the command line? The toolchain file is loaded very early, before any of the platform information files. It is supposed to provide information, not consume it. It is loaded too early to even know CMAKE_SYSTEM_NAME, because it is supposed to provide this value. Thanks for the answers! From what I understand, I missed the point of the cross compilation file a bit, and I should rather go for platform files. For cross-compiling a project on iOS or iOS simulator, and since those 2 platforms are still Darwin, I believe that: * from a user perspective: * CMAKE_SYSTEM_NAME should be set to "Darwin" * CMAKE_SYSTEM_VERSION should be set to iOS or iOS-simulator, possibly with a version (like "Mac OSX 10.2" in Darwin.cmake) * inside "Modules/Platform/Darwin.cmake" * CMAKE_SYSTEM_PROCESSOR should default to armXX for iOS and i386/x86_64 for the simulator * I do not think that any other compiler than AppleClang is supported, but we leave the detection as it is right now. This should default to AppleClang anyway. * the detection of the base SDKs should be performed inside "Platform/Darwin.cmake" * the file "Modules/Platform/Darwin-Clang.cmake" should check the "CMAKE_SYSTEM_VERSION" to add appropriate flags when CMAKE_SYSTEM_VERSION is iOS or simulator. This should include clang and apple clang. If things work ok and if I understand more or less the scope of those files, the base SDKs will then be detected from the "Modules/Platform/Darwin.cmake". However, I just notice the existence of "Modules/Platform/Darwin-Initialize.cmake" that is setting several variables. When is this file sourced? should be before "Modules/Platform/Darwin.cmake" but I failed to see from where. I see several problems with this file if I were to make it iOS aware. For instance it contains variables that are checking for the version, but based only on the macOS scheme. Should the CMAKE_SYSTEM_VERSION include the "iOS" or "iOSSimulator" part? (like for instance "iOS-10.1" ?) or we stick to a clean version name and: 1/ either we change the CMAKE_SYSTEM_NAME to DarwinIOS (we also need to distinguish between real device and simulator) 2/ or we carry another variable IOS=TRUE and be careful inside the Darwin specific platform files. My preference goes for 2/ above because: * having something like DarwinIOS would need to create a full new branch of platform support, while the overlap with Darwin is almost 95%. * iOS is clearly a Darwin platform, just another version, but version carries more than a revision number (eg "10.5") that needs to be encoded in another variable (eg. IOS=TRUE) * we will benefit from all the build logic (Darwin, policies, etc) that are currently working for OSX Also, is it possible to check for policies directly from the toolchain file, or is it too early? In a project that starts with `cmake_minimum_required(...)` as its first call (the recommended approach) then policies it sets will be available when the toolchain file is first loaded by a following `project()` or `enable_language()` command. However, toolchain files are not meant to be general-purpose infrastructure shared by many projects. They are meant to be specific to a project and host machine. Common info about a platform belongs in CMake's modules, e.g. a Platform/iOS.cmake module for use with CMAKE_SYSTEM_NAME set to "iOS". Lacking that, a toolchain file trying to work without it will undoubtedly need to be hacky. I believe if I integrate well with the platform files, all things would be good again, and the policies will apply naturally (so no hack needed). This is what I added in the toolchain file, but I feel like this is too hacky: set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE) set(CMAKE_INSTALL_NAME_DIR "@rpath/") set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_INSTALL_RPATH "@rpath/") If that is universally needed when deploying to iOS then CMake should be taught this information in a corresponding platform file. I do not think this is universally needed, I just wanted to mimic the default I got when compiling the same source tree but with the OSX target platform. Without great success ... Keeping it in the toolchain file may work but is an example of the hacky nature discussed above. OTOH this looks project-specific to me. One could use `@executable_path/` in INSTALL_NAME_DIR for everything and not need any rpath. Yes, I was not convinced neither and totally fine with removing this. and I need to also do this: set_target_properties(mymainexecutable PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH "@executable_path/" ) This encodes knowledge of the relative install destination of the libraries to the executable, which only the project code itself can know.
Re: [cmake-developers] iOS: direction to official support and questions
On 09/26/2017 05:05 PM, Raffi Enficiaud wrote: > Is it possible to source the default setup and to override some parts > when a toolchain is given on the command line? The toolchain file is loaded very early, before any of the platform information files. It is supposed to provide information, not consume it. It is loaded too early to even know CMAKE_SYSTEM_NAME, because it is supposed to provide this value. > Also, is it possible to check for policies directly from the toolchain > file, or is it too early? In a project that starts with `cmake_minimum_required(...)` as its first call (the recommended approach) then policies it sets will be available when the toolchain file is first loaded by a following `project()` or `enable_language()` command. However, toolchain files are not meant to be general-purpose infrastructure shared by many projects. They are meant to be specific to a project and host machine. Common info about a platform belongs in CMake's modules, e.g. a Platform/iOS.cmake module for use with CMAKE_SYSTEM_NAME set to "iOS". Lacking that, a toolchain file trying to work without it will undoubtedly need to be hacky. > This is what I added in the toolchain file, but I feel like this is too > hacky: > > set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE) > set(CMAKE_INSTALL_NAME_DIR "@rpath/") > set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) > set(CMAKE_INSTALL_RPATH "@rpath/") If that is universally needed when deploying to iOS then CMake should be taught this information in a corresponding platform file. Keeping it in the toolchain file may work but is an example of the hacky nature discussed above. OTOH this looks project-specific to me. One could use `@executable_path/` in INSTALL_NAME_DIR for everything and not need any rpath. > and I need to also do this: > set_target_properties(mymainexecutable >PROPERTIES > BUILD_WITH_INSTALL_RPATH TRUE > INSTALL_RPATH "@executable_path/" > ) This encodes knowledge of the relative install destination of the libraries to the executable, which only the project code itself can know. -Brad -- 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
Re: [cmake-developers] iOS: direction to official support and questions
Le 21.09.17 à 23:38, Raffi Enficiaud a écrit : 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 Hi CMake, I do not know if anyone here had the chance to try the previous toolchain file. Since then, I have now a real device and some new fixing has started on my side. One of the issues I am facing right now is the one concerning the RPATH generation on iOS. I think the best approach is to mimic the one for OSX/macOS, but I do not know how this would be feasible. The main question is: Is it possible to source the default setup and to override some parts when a toolchain is given on the command line? Also, is it possible to check for policies directly from the toolchain file, or is it too early? This is what I added in the toolchain file, but I feel like this is too hacky: set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE) set(CMAKE_INSTALL_NAME_DIR "@rpath/") set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_INSTALL_RPATH "@rpath/") and I need to also do this: set_target_properties(mymainexecutable PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH "@executable_path/" ) for the main executable (I need to bundle additional ".dylibs" into the main application). For some reason, the CMAKE_* variables do not always propagate well to the targets (using cmake 3.7). Any hint or good practice welcome! Thanks, Raffi -- 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
Re: [cmake-developers] iOS: direction to official support and questions
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_BUILD COMMAND ${CMAKE_COMMAND} -DAPPFOLDER=$/${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
Re: [cmake-developers] iOS: direction to official support and questions
Le 16.08.17 à 16:27, Eric Wing a écrit : I've been using a derivative of the iOS toolchain for many years that you probably can find easily with a Google search. It has a lot of shortcomings, but it generally works. And most of the shortcomings I think are only solvable by properly fixing/modifying the CMake core. Hi, thanks for your answer. I also found several examples online, some of them are good, but I cannot just copy-paste them :) I need to understand what is going on, and sometimes things are done not in a good way. On 8/15/17, Raffi Enficiaudwrote: Le 10.08.17 à 17:04, Brad King a écrit : On 08/08/2017 08:08 AM, Raffi Enficiaud wrote: I have looked a bit to the Android toolchains, and I have to say I found those quite complicated as a first reading :) I personally think the Android toolchain is way more complicated than the iOS toolchain. Among the reasons are that every NDK release broke something different as they kept changing the compiler and conventions (the gcc to clang move was the most recent biggie, but old-timers might remember the standalone toolchain difficulties.). Then you have to pick different API levels because the each NDK release ships a separate API subtarget for all prior versions of Android. Then add all the multiple architectures (mips, arm, x86, 64-bit) and the subvariants (armv5, armv7, armv7+NEON, etc), 4 different C++ standard libraries you have to choose from, and other nuisances like Android on Windows...makes the whole thing a mess. Right now, I am completely discarding whatever has been done for Android :) Ideally CMake would gain iOS platform modules such that one could set CMAKE_SYSTEM_NAME to `iOS`. where this path is hard coded, and points to the fat static libraries prefix path of boost. If I remove this path, FindBoost does not find the boost libraries anymore (of course I am passing BOOST_ROOT). In addition, I have this: set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) These last three lines tell the find commands to only look at paths re-rooted under CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT. If boost is not under one of those then it won't be found. That sounds right. The general problem is you don't want to accidentally pick up OSX stuff on your system. It appears that this is too restrictive. For instance, I compiled boost and made fat libraries in an installation folder, and I am not being able to pick them up. By removing them, FindBoost works fine. But the problem is that it is unclear to me what should be allowed and what not, and where are the problems: * specifically for the FindBoost problem mentioned above, is it a limitation of FindBoost that is not honouring cross compilation well? I believe that if I provide a BOOST_ROOT, then it should be used no matter what default configuration is provided by the toolchain file * another example: I need eg. the python interpreter to run some tests. If I remove the lines above, the host interpreter is found. In the case of my project, it is ok, because I use that for running some tests. In some other projects I have, I think this is not ok because I may use the interpreter for finding other libraries on the OS (cython, numpy, etc). The question is: what is the best practice for letting the developer do his job right? Preventing accessing some paths when searching for a binary or a shared/library is limiting. Especially, it is not easy to know if a library that is found is part of the cross-compilation toolchain that can run on the host (say "codesign", "clang", "python" etc) or part of the bundle we want to create (eg boost_something.dylib, that is a fat binary containing also the architecture of the host - because of the iOS simulator). As of today, find_library or find_program does not make any distinction, but in case of cross-compilation, I would like to have ideally a "CROSS_COMPILATION_TOOLCHAIN" property that I may use in the CMake scripts. For instance, I need to find a library that will be integrated in the target platform binary: find_library(MyLIB NAMES my_lib_arch_arm TARGET_PLATFORM) # or TARGET_PLATFORM implicit add_executable(MyFinalBundle ... TARGET_PLATFORM) target_link_library(MyFinalBundle MyLIB) # check for consistency: all dependencies should be TARGET_PLATFORM as well In this case, the find_library will look into the sysroot that is provided by the toolchain file, plus some given by the user and that are specific to the module (BOOST_ROOT for instance) OTOH: find_library(MyToolchainLib NAMES my_toolchainlib HOST_PLATFORM) find_program(my_other_toolchain_program HOST_PLATFORM) add_executable(my_intermediade_tool HOST_PLATFORM) target_link_library(my_intermediade_tool MyToolchainLib) add_custom_command( OUTPUT output output2 COMMAND
Re: [cmake-developers] iOS: direction to official support and questions
I've been using a derivative of the iOS toolchain for many years that you probably can find easily with a Google search. It has a lot of shortcomings, but it generally works. And most of the shortcomings I think are only solvable by properly fixing/modifying the CMake core. On 8/15/17, Raffi Enficiaudwrote: > Le 10.08.17 à 17:04, Brad King a écrit : >> On 08/08/2017 08:08 AM, Raffi Enficiaud wrote: >>> I have looked a bit to the Android toolchains, and I have to say I found >>> those quite complicated as a first reading :) >> I personally think the Android toolchain is way more complicated than the iOS toolchain. Among the reasons are that every NDK release broke something different as they kept changing the compiler and conventions (the gcc to clang move was the most recent biggie, but old-timers might remember the standalone toolchain difficulties.). Then you have to pick different API levels because the each NDK release ships a separate API subtarget for all prior versions of Android. Then add all the multiple architectures (mips, arm, x86, 64-bit) and the subvariants (armv5, armv7, armv7+NEON, etc), 4 different C++ standard libraries you have to choose from, and other nuisances like Android on Windows...makes the whole thing a mess. >> Ideally CMake would gain iOS platform modules such that one could >> set CMAKE_SYSTEM_NAME to `iOS`. >>> where this path is hard coded, and points to the fat static libraries >>> prefix path of boost. If I remove this path, FindBoost does not find the >>> boost libraries anymore (of course I am passing BOOST_ROOT). In >>> addition, I have this: >>> >>> set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) >>> set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) >>> set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) >> >> These last three lines tell the find commands to only look at >> paths re-rooted under CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT. >> If boost is not under one of those then it won't be found. >> That sounds right. The general problem is you don't want to accidentally pick up OSX stuff on your system. I've generally used a combination of two things. I modified my toolchain to have special new root paths which I can define and I put all my iOS stuff there, and/or I use the -C initial cache feature of CMake to prespecify the locations. (And sometimes my initial caches use my new root path variables so the initial cache is flexible and not hard coded.) >>> set(CMAKE_MACOSX_BUNDLE YES) >> >> Is it possible to build any binary of any form on iOS without this? > > You're right, I do not think this is possible. As far as I know, it always must be a bundle. > As I understand it, this is a problem of try_compile: as signing of > application is required for generating a binary for iOS, this one fails very > early when CMake discovers the capabilities of the compiler. I have not encountered this. I don't think it is true, but I rarely use try_compile. Building iOS static libraries are not signed. And I don't think simulator targets require signing either. Signing is required for running on device. That said, there are a ton of other problems related to signing which are completely broken with CMake. Right now, the biggest pain point for me is the new Automatic Code signing. Prior to Xcode 8, you could set a CMake Xcode attribute to explicitly set the key to use. But this now conflicts with the new Automatic Code signing, and this his cannot be controlled by a CMake attribute and it breaks everything. And even if that were fixed, Xcode needs a second property, the Team. While this can be set by an attribute, the problem is just about every user has a different team and it is not easy to know. Xcode has a way of finding out what teams are available so you can pick it in a drop-down list (same with the keys). But for a CMake user, this is nearly impossible to know apriori. I think the only way to fix this is to modify CMake to 1) try to defer to Xcode's built-in behavior & 2) if the user sets this, some how don't let CMake overwrite/clobber just that setting when the project regenerates on an update. Semi-related is the Mac OS X entitlements system which is connected to code signing and shipping on the Mac App Store. It has a lot of these same problems and I think it needs to be fixed in the same fashion. The entitlements are supposed to show up in a dedicated tab in the project settings, but CMake projects tend to be blank in this area. And related to that is the iOS device orientation and launch screen setting which is the same story. > > Currently the main issue I am seeing is the multiarch/multisysroot > target of XCode that is kind of lost when using CMake. By > multiarch/multisysroot, I mean that Xcode is able to switch from > iPhoneSimulatorXY to iPhoneXY without changing the project, and within > the same view. Yes, that is a huge problem. I've found this to be very fragile. However for the moment, it kind of works.
Re: [cmake-developers] iOS: direction to official support and questions
There's discussions related to problems with linking and multiple architectures in the following recent thread too: http://public.kitware.com/pipermail/cmake-developers/2017-August/030192.html Eric highlights a number of similar issues to those you've mentioned. Have a read through the whole thread to get a deeper understanding, but it sounds like you're already familiar with at least some of the problems. On Wed, Aug 16, 2017 at 10:45 AM, Raffi Enficiaud < raffi.enfici...@mines-paris.org> wrote: > Le 10.08.17 à 17:04, Brad King a écrit : > >> On 08/08/2017 08:08 AM, Raffi Enficiaud wrote: >> >>> I have looked a bit to the Android toolchains, and I have to say I found >>> those quite complicated as a first reading :) >>> >> >> This note may help: >> >> https://gitlab.kitware.com/cmake/cmake/issues/16708#note_300971 >> > > Hi, > Thanks for the link and the answers! > > > I don't think iOS will need all the toolchain and stl selection logic. >> >> Ideally CMake would gain iOS platform modules such that one could >> set CMAKE_SYSTEM_NAME to `iOS`. >> >> set(CMAKE_FIND_ROOT_PATH >>> ${CMAKE_IOS_DEVELOPER_ROOT} >>> ${CMAKE_IOS_SDK_ROOT} >>> ${CMAKE_PREFIX_PATH} >>> /path/to/boost_1_64_0_build/install >>> CACHE string "iOS find search path root") >>> ``` >>> >>> where this path is hard coded, and points to the fat static libraries >>> prefix path of boost. If I remove this path, FindBoost does not find the >>> boost libraries anymore (of course I am passing BOOST_ROOT). In >>> addition, I have this: >>> >>> set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) >>> set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) >>> set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) >>> >> >> These last three lines tell the find commands to only look at >> paths re-rooted under CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT. >> If boost is not under one of those then it won't be found. >> >> set(CMAKE_MACOSX_BUNDLE YES) >>> >> >> Is it possible to build any binary of any form on iOS without this? >> > > You're right, I do not think this is possible. > > If not then the iOS platform modules should set something to tell >> the generators that this should always be enabled. >> >> set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") >>> >> >> Similarly for this, but perhaps only during `try_compile`. >> > > What I understand from this variable is that, it sets the default of > CODE_SIGNING_REQUIRED to "NO", and this can be overriden per target by > setting the XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED target property to > something else. > > Is that correct? > > I believe that for iOS developments, the default should rather be the > opposite, and the try_compile should be informed of not trying to sign the > app, via "some mechanism" as you suggested. > > Concerning this "some mechanism" part, what do you have in mind? Would it > be an extra variable like > CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED_IN_TRY_COMPILE > ? > > What I fail to understand here, is the purpose of the "try_compile" that > is performed at the beginning. Isn't this try_compile supposed to compile > source files only, without trying to link nor bundle anything? If this is > the case, signing the result is irrelevant, and I do not understand why > this fails. > > If you have an idea, good, otherwise I believe this is secondary right now. > > I'm not familiar enough with iOS development to answer the rest of >> your questions. >> > > Me neither :) > > Currently the main issue I am seeing is the multiarch/multisysroot target > of XCode that is kind of lost when using CMake. By multiarch/multisysroot, > I mean that Xcode is able to switch from iPhoneSimulatorXY to iPhoneXY > without changing the project, and within the same view. > > The switching means changing the target architecture, as well as changing > the SYSROOT. I checked the command lines emitted by XCode, and it changes > the "-isysroot" flag based on the type of target. > > From the posts I can read online, this is causing a lot of troubles, > especially when linking with libraries. > > For users' libraries, the workaround is to have fat libraries by combining > all the target archs into one with lipo. The compilation is done with > different "-isysroot" then. What I understood is that Apple is discouraging > this, and this is for me not a proper solution neither, but might work. > > The real problem seems to be when linking to system libraries, those that > are under sysroot, and I cannot find a good answer to this. > > Example: > > Suppose in the toolchain file, we have something like this, where > CMAKE_IOS_SDK_ROOT depends on the fact that we use the simulator or not: > > ''' > set(CMAKE_FIND_ROOT_PATH > ${CMAKE_IOS_DEVELOPER_ROOT} > ${CMAKE_IOS_SDK_ROOT} > ${CMAKE_PREFIX_PATH} > /some/other/path > CACHE string "iOS find search path root") > > # set up the default search directories for frameworks > set (CMAKE_SYSTEM_FRAMEWORK_PATH >
Re: [cmake-developers] iOS: direction to official support and questions
Le 10.08.17 à 17:04, Brad King a écrit : On 08/08/2017 08:08 AM, Raffi Enficiaud wrote: I have looked a bit to the Android toolchains, and I have to say I found those quite complicated as a first reading :) This note may help: https://gitlab.kitware.com/cmake/cmake/issues/16708#note_300971 Hi, Thanks for the link and the answers! I don't think iOS will need all the toolchain and stl selection logic. Ideally CMake would gain iOS platform modules such that one could set CMAKE_SYSTEM_NAME to `iOS`. set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} /path/to/boost_1_64_0_build/install CACHE string "iOS find search path root") ``` where this path is hard coded, and points to the fat static libraries prefix path of boost. If I remove this path, FindBoost does not find the boost libraries anymore (of course I am passing BOOST_ROOT). In addition, I have this: set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) These last three lines tell the find commands to only look at paths re-rooted under CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT. If boost is not under one of those then it won't be found. set(CMAKE_MACOSX_BUNDLE YES) Is it possible to build any binary of any form on iOS without this? You're right, I do not think this is possible. If not then the iOS platform modules should set something to tell the generators that this should always be enabled. set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") Similarly for this, but perhaps only during `try_compile`. What I understand from this variable is that, it sets the default of CODE_SIGNING_REQUIRED to "NO", and this can be overriden per target by setting the XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED target property to something else. Is that correct? I believe that for iOS developments, the default should rather be the opposite, and the try_compile should be informed of not trying to sign the app, via "some mechanism" as you suggested. Concerning this "some mechanism" part, what do you have in mind? Would it be an extra variable like CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED_IN_TRY_COMPILE ? What I fail to understand here, is the purpose of the "try_compile" that is performed at the beginning. Isn't this try_compile supposed to compile source files only, without trying to link nor bundle anything? If this is the case, signing the result is irrelevant, and I do not understand why this fails. If you have an idea, good, otherwise I believe this is secondary right now. I'm not familiar enough with iOS development to answer the rest of your questions. Me neither :) Currently the main issue I am seeing is the multiarch/multisysroot target of XCode that is kind of lost when using CMake. By multiarch/multisysroot, I mean that Xcode is able to switch from iPhoneSimulatorXY to iPhoneXY without changing the project, and within the same view. The switching means changing the target architecture, as well as changing the SYSROOT. I checked the command lines emitted by XCode, and it changes the "-isysroot" flag based on the type of target. From the posts I can read online, this is causing a lot of troubles, especially when linking with libraries. For users' libraries, the workaround is to have fat libraries by combining all the target archs into one with lipo. The compilation is done with different "-isysroot" then. What I understood is that Apple is discouraging this, and this is for me not a proper solution neither, but might work. The real problem seems to be when linking to system libraries, those that are under sysroot, and I cannot find a good answer to this. Example: Suppose in the toolchain file, we have something like this, where CMAKE_IOS_SDK_ROOT depends on the fact that we use the simulator or not: ''' set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} /some/other/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 ) ''' and later in our CMakeLists, we have eg. ''' find_package(ZLIB REQUIRED) ''' The selection of the SYSROOT is done then on the cmd line given to CMake, and set up once. The library that is found by ZLIB are related to CMAKE_IOS_SDK_ROOT, that is a constant in a build tree. Although Xcode can reroot the SYSROOT depending on the target device/arch (simulator/non-simulator). Even if later XCode is able to switch sysroots on the command line, depending on the target, the libraries we are linking to are constant, and not honoring the dynamically determined sysroot anymore. I believe this
Re: [cmake-developers] iOS: direction to official support and questions
On 08/08/2017 08:08 AM, Raffi Enficiaud wrote: > I have looked a bit to the Android toolchains, and I have to say I found > those quite complicated as a first reading :) This note may help: https://gitlab.kitware.com/cmake/cmake/issues/16708#note_300971 I don't think iOS will need all the toolchain and stl selection logic. Ideally CMake would gain iOS platform modules such that one could set CMAKE_SYSTEM_NAME to `iOS`. > set(CMAKE_FIND_ROOT_PATH > ${CMAKE_IOS_DEVELOPER_ROOT} > ${CMAKE_IOS_SDK_ROOT} > ${CMAKE_PREFIX_PATH} > /path/to/boost_1_64_0_build/install > CACHE string "iOS find search path root") > ``` > > where this path is hard coded, and points to the fat static libraries > prefix path of boost. If I remove this path, FindBoost does not find the > boost libraries anymore (of course I am passing BOOST_ROOT). In > addition, I have this: > > set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) > set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) > set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) These last three lines tell the find commands to only look at paths re-rooted under CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT. If boost is not under one of those then it won't be found. > set(CMAKE_MACOSX_BUNDLE YES) Is it possible to build any binary of any form on iOS without this? If not then the iOS platform modules should set something to tell the generators that this should always be enabled. > set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") Similarly for this, but perhaps only during `try_compile`. I'm not familiar enough with iOS development to answer the rest of your questions. -Brad -- 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
[cmake-developers] iOS: direction to official support and questions
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). I can share the toolchain file: it is a collection of things I have found on the internet, but trimmed from what I think was not necessary. It is still in a not so nice state, but I am currently cleaning it. There are things that I think are weird though: * I need to have: ``` set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} /path/to/boost_1_64_0_build/install CACHE string "iOS find search path root") ``` where this path is hard coded, and points to the fat static libraries prefix path of boost. If I remove this path, FindBoost does not find the boost libraries anymore (of course I am passing BOOST_ROOT). In addition, I have this: ``` 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 ) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) ``` this looks ok to me, as we are cross compiling. Is this a problem of FindBoost, or the combinations of the options that are not ok? * I need to add: ``` set(CMAKE_MACOSX_BUNDLE YES) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") ``` and this comes from https://public.kitware.com/Bug/view.php?id=15329 . As I understand it, this is a problem of try_compile: as signing of application is required for generating a binary for iOS, this one fails very early when CMake discovers the capabilities of the compiler. Some people made a workaround by short-cutting the compiler checks, which is to me a wrong direction to take. As mentioned in this ticket, the right solution would be that the try_compile commands not to require signing of the binaries (or sthg similar). This is explained here: http://public.kitware.com/Bug/view.php?id=12288 * is this one https://cmake.org/Bug/view.php?id=12640 addressed? * I am seeing exchanges concerning the IOS_INSTALL_COMBINED. Does this has something to do with toolchain? What is meant by "installation" in this case? Sorry for my naive question, but I do not understand the workflow very well. * how can I have unit tests of the toolchain in a CI fashion. Ideally, I would like to have a target cross-compiled with this toolchain, and then running the iPhoneSimulator, and check the result (return code, process, command whatever). Does anyone have experience with this? Thanks, Raffi -- 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