Skip to content

Add initial iOS support#6275

Merged
vicroms merged 2 commits intomicrosoft:masterfrom
alcroito:ios_support
Apr 15, 2020
Merged

Add initial iOS support#6275
vicroms merged 2 commits intomicrosoft:masterfrom
alcroito:ios_support

Conversation

@alcroito
Copy link
Contributor

@alcroito alcroito commented May 1, 2019

Crude implementation of #6003

At the moment I don't think it makes sense to merge this. There are still some iOS bugs in CMake upstream that are pending fixes, and something like iOS support would definitely need more discussion.

Nevertheless, I wanted to share what I've worked on so far, in case anybody is interested in testing it, or maybe improving it. Also to get some opinions if something like iOS support would ever be accepted to mainline vcpkg.

I've successfully built zlib, libpng, pcre2, libjpeg-turbo, double-conversion and freetype targeting arm64-ios, using latest CMake 3.14.3.

I have then successfully used the packages to build parts of Qt (again targeting iOS) using CMake.

@alcroito alcroito mentioned this pull request May 1, 2019
@grdowns grdowns added the wip label May 2, 2019
@Rastaban
Copy link
Contributor

Rastaban commented May 6, 2019

Thank you for your PR! We are interested in officially supporting iOS, it is just a matter of timing (so we can do things like build up the testing infrastructure). This PR may sit here for a bit while we figure out those things but so far I think I like the direction this is going.

@alcroito
Copy link
Contributor Author

I rebased my PR on top of latest master (fixed some conflicts).
This also changes the triplets to make sure the built libraries will be static libraries. Thus it's conforming with the osx and linux triplets.
Also slightly modified the commit message.

@cbezault
Copy link
Contributor

The time is coming soon that we're going to stand up some infrastructure to test this.

@alcroito alcroito force-pushed the ios_support branch 2 times, most recently from 142f6f5 to 98234ac Compare July 29, 2019 16:04
@cbezault cbezault assigned vicroms and unassigned cbezault Oct 2, 2019
@a4z
Copy link
Contributor

a4z commented Nov 16, 2019

what is the current status and plan for vcpkg and iOS ?
sorry for asking here, but it seems the best place a web search brings

@alcroito
Copy link
Contributor Author

Rebased on latest master

@JackBoosY
Copy link
Contributor

/azp run

@JackBoosY
Copy link
Contributor

If this PR is ready to review, please ping me.

Thanks.

@alcroito alcroito changed the title [WIP] Add initial iOS support Add initial iOS support Jan 20, 2020
@alcroito
Copy link
Contributor Author

alcroito commented Jan 20, 2020

@JackBoosY Ready for review.

I also added community triplets for iOS.

Successfully built/installed the following packages using CMake 3.16, Xcode 13.1 for the arm64-ios, x86-ios, x64-ios triplets:

zlib pcre2 harfbuzz freetype zstd sqlite3 libpng double-conversion

The arm-ios would require a lower Xcode to test fully, although at least zlib built successfully.

@JackBoosY JackBoosY removed the wip label Jan 21, 2020
@JackBoosY
Copy link
Contributor

Please resolve osx regression:

[1/32] cd /Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg && /Users/vagrant/Data/downloads/tools/cmake-3.14.0-osx/cmake-3.14.0-Darwin-x86_64/CMake.app/Contents/bin/cmake -DOUTPUT=pngprefix.h -P /Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg/scripts/gensrc.cmake
[2/32] cd /Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg && /Users/vagrant/Data/downloads/tools/cmake-3.14.0-osx/cmake-3.14.0-Darwin-x86_64/CMake.app/Contents/bin/cmake -DINPUT=/Users/vagrant/azure-agent/_work/2/s/buildtrees/libpng/src/v1.6.37-97c9fa9531/scripts/symbols.c -DOUTPUT=/Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg/scripts/symbols.out -P /Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg/scripts/genout.cmake
FAILED: scripts/symbols.out 
cd /Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg && /Users/vagrant/Data/downloads/tools/cmake-3.14.0-osx/cmake-3.14.0-Darwin-x86_64/CMake.app/Contents/bin/cmake -DINPUT=/Users/vagrant/azure-agent/_work/2/s/buildtrees/libpng/src/v1.6.37-97c9fa9531/scripts/symbols.c -DOUTPUT=/Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg/scripts/symbols.out -P /Users/vagrant/Data/buildtrees/libpng/x64-osx-dbg/scripts/genout.cmake
CMake Error at scripts/genout.cmake:28 (list):
  list GET given empty list

@alcroito
Copy link
Contributor Author

Regression addressed.

@JackBoosY
Copy link
Contributor

Fixed.

alcroito and others added 2 commits April 15, 2020 11:25
Added an iOS toolchain to enable building packages for iOS.
The toolchain is used when a triplet's VCPKG_CMAKE_SYSTEM_NAME is set
to iOS.

To configure which architecture should be built, as well as other
iOS specifics, the following triplet variables can be set:
- VCPKG_TARGET_ARCHITECTURE
- VCPKG_OSX_SYSROOT
- VCPKG_OSX_DEPLOYMENT_TARGET
- VCPKG_OSX_ARCHITECTURES

The following VCPKG_TARGET_ARCHITECTURE values are currently
supported:
 - arm, arm64, x64, x86.

The following VCPKG_OSX_SYSROOT values are currently supported:
 - iphoneos, iphonesimulator, or an absolute path to the device or
   simulator Xcode SDK.

VCPKG_OSX_DEPLOYMENT_TARGET can be set to control the minimum iOS
delopyment target for the built libraries.

CMAKE_OSX_ARCHITECTURES is derived from VCPKG_TARGET_ARCHITECTURE,
so generally it should not be set. In case if someone needs to target
a more specific architecture (like armv7k or arm64e), it can
be set in the triplet via VCPKG_OSX_ARCHITECTURES.

Note that only certain combinations of the architecture and sysroot
will work: simulator SDKs only provide x86-based libraries, etc.

The toolchain also sets CMAKE_SYSTEM_PROCESSOR for certain
configurations, because certain packages (like libpng) depend on the
processor type.

Added 4 community iOS triplets that build static libraries:
- arm-ios, arm64-ios, x86-ios, x64-ios.
The non-arm triplets target the iOS simulator.

The triplets build static libraries because they are easiest to
integrate into an iOS project. Dynamic libraries or frameworks require
code signing on iOS, which complicates integration.

Added heuristics to try and automatically detect what iOS triplet to
use when building your own CMake project (so when a CMake project sets
CMAKE_TOOLCHAIN_FILE to buildsystems/vcpkg.cmake), if no explicit
triplet is provided (VCPKG_TARGET_TRIPLET is undefined).

The heuristic checks for the values of CMAKE_SYSTEM_NAME and
CMAKE_OSX_ARCHITECTURES. Note that for this to work,
CMAKE_OSX_ARCHITECTURES needs to be set before the first project()
call in your CMake project.

Added workaround so find_package finds vcpkg installed packages
when targeting iOS.
This is done by saving / restoring the value of CMAKE_FIND_ROOT_PATH
while also adding the vcpkg package root in the find_package override
macro.
The workaround can be removed once vcpkg upgrades to CMake 3.15.0
or higher where the issue is fixed.

Fixes: microsoft#6003
Copy link
Contributor

@JackBoosY JackBoosY left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove podofo:x64-osx=fail in VCPKG_PATH/scripts/ci.baseline.txt.

@alcroito
Copy link
Contributor Author

Sorry, pushed wrong branch. Should be fine now.

@vicroms
Copy link
Member

vicroms commented Apr 15, 2020

@alcroito
Thanks for the great PR!

@vicroms vicroms merged commit c5f01e1 into microsoft:master Apr 15, 2020
@leha-bot
Copy link
Contributor

Stupid question: Should I install vcpkg on iMac for building vcpkg ports, or it could magically works on my main Windows host?

@luncliff
Copy link
Contributor

luncliff commented May 4, 2020

@leha-bot sadly, you have to use Apple Platform. You can try port build using Travis CI or Azure Pipelines build job, publish the ${vcpkg}/installed directory, and download them later.

@christophe-calmejane
Copy link
Contributor

Hi,
I don't get how one can install an ios port with just that PR.
Whenever I try, I get this error Unable to determine toolchain to use for triplet x64-ios with CMAKE_SYSTEM_NAME iOS
Shouldn't build.cpp fs::path PreBuildInfo::toolchain_file() const method handle iOS toolchain?

@alcroito
Copy link
Contributor Author

alcroito commented Jul 9, 2020

Apparently there have been changes in how toolchains and community triplets are handled since this PR merged, and that broke iOS support. Somebody mentioned about it in the comments of this issue #12065

@christophe-calmejane
Copy link
Contributor

I locally patched build.cpp to handle ios and it looks to be ok (I yet have to test a lib with an actual project to be sure).
I encountered another error while trying to build openssl (ios is not handled in the CMakeLists.txt, and when trying to fix it, I noticed CMAKE_SYSTEM_PROCESSOR is not defined (although CMAKE_SYSTEM_NAME is). Maybe it's related to the changes that occurred to community triplets also, because based on this PR, CMAKE_SYSTEM_PROCESSOR is set in the toolchain script.

@JackBoosY
Copy link
Contributor

@alcroito Could you fix this issue?

Thanks.

@christophe-calmejane
Copy link
Contributor

christophe-calmejane commented Jul 10, 2020

Hi,
this is what I ended up patching:

  • iOS support for boost and openssl
  • Disabling code signing during find_package (for try-compile), otherwise find_package(Threads) will fail
  • Fix iOS toolchain
diff --git a/ports/boost-modular-build-helper/boost-modular-build.cmake b/ports/boost-modular-build-helper/boost-modular-build.cmake
index a70363ee4..2281fbc4b 100644
--- a/ports/boost-modular-build-helper/boost-modular-build.cmake
+++ b/ports/boost-modular-build-helper/boost-modular-build.cmake
@@ -19,6 +19,8 @@ function(boost_modular_build)
     # Todo: this serves too similar a purpose as vcpkg_find_acquire_program()
     if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "Linux" AND VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
         set(BOOST_BUILD_PATH "${CURRENT_INSTALLED_DIR}/../x64-linux/tools/boost-build")
+    elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "iOS" AND (VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm"))
+        set(BOOST_BUILD_PATH "${CURRENT_INSTALLED_DIR}/../x64-osx/tools/boost-build")
     elseif(CMAKE_HOST_WIN32 AND VCPKG_CMAKE_SYSTEM_NAME AND NOT VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND NOT VCPKG_CMAKE_SYSTEM_NAME STREQUAL "MinGW")
         get_filename_component(BOOST_BUILD_PATH "${CURRENT_INSTALLED_DIR}/../x86-windows/tools/boost-build" ABSOLUTE)
     elseif(NOT VCPKG_TARGET_ARCHITECTURE STREQUAL "x64" AND NOT VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")
@@ -29,9 +31,11 @@ function(boost_modular_build)
 
     if(NOT EXISTS "${BOOST_BUILD_PATH}")
         if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "Linux" AND VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
-            message(FATAL_ERROR "The x64 boost-build tools must be installed to build arm64 for Linux. Please run `vcpkg install boost-build:x64-linux`.") 
+            message(FATAL_ERROR "The x64 boost-build tools must be installed to build arm64 for Linux. Please run `vcpkg install boost-build:x64-linux`.")
+        elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "iOS" AND (VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm"))
+            message(FATAL_ERROR "The x64 boost-build tools must be installed to build arm64 for iOS. Please run `vcpkg install boost-build:x64-osx`.")
         else()
-            message(FATAL_ERROR "The x86 boost-build tools must be installed to build for non-x86/x64 platforms. Please run `vcpkg install boost-build:x86-windows`.")
+            message(FATAL_ERROR "The x86 boost-build tools must be installed to build for non-x86/x64 platforms. Please run `vcpkg install boost-build:x86-windows`.: ${VCPKG_TARGET_ARCHITECTURE}")
         endif()
     endif()
 
diff --git a/ports/openssl-unix/CMakeLists.txt b/ports/openssl-unix/CMakeLists.txt
index 7857058f0..3a353524b 100644
--- a/ports/openssl-unix/CMakeLists.txt
+++ b/ports/openssl-unix/CMakeLists.txt
@@ -15,6 +15,18 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
     set(PLATFORM darwin64-x86_64-cc)
 elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
     set(PLATFORM BSD-generic64)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+        set(PLATFORM darwin64-x86_64-cc)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i386")
+        set(PLATFORM darwin-i386-cc)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
+        set(PLATFORM ios64-xcrun)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
+        set(PLATFORM ios-xcrun)
+    else()
+        message(FATAL_ERROR "Unknown system processor")
+    endif()
 else()
     message(FATAL_ERROR "Unknown platform")
 endif()
diff --git a/scripts/buildsystems/vcpkg.cmake b/scripts/buildsystems/vcpkg.cmake
index 96f847190..3c7c35451 100644
--- a/scripts/buildsystems/vcpkg.cmake
+++ b/scripts/buildsystems/vcpkg.cmake
@@ -376,7 +376,11 @@ macro(${VCPKG_OVERRIDE_FIND_PACKAGE_NAME} name)
         set(Boost_NO_BOOST_CMAKE ON)
         unset(Boost_USE_STATIC_RUNTIME CACHE)
         set(Boost_COMPILER "-vc140")
+        set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES "CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED")
+        set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
         _find_package(${ARGV})
+        unset(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES)
+        unset(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED)
     elseif("${name}" STREQUAL "ICU" AND EXISTS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/unicode/utf.h")
         function(_vcpkg_find_in_list)
             list(FIND ARGV "COMPONENTS" COMPONENTS_IDX)
@@ -412,7 +416,11 @@ macro(${VCPKG_OVERRIDE_FIND_PACKAGE_NAME} name)
     elseif("${_vcpkg_lowercase_name}" STREQUAL "grpc" AND EXISTS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share/grpc")
         _find_package(gRPC ${ARGN})
     else()
+        set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES "CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED")
+        set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
         _find_package(${ARGV})
+        unset(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES)
+        unset(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED)
     endif()
     if(CMAKE_SYSTEM_NAME STREQUAL iOS)
         set(CMAKE_FIND_ROOT_PATH "${BACKUP_CMAKE_FIND_ROOT_PATH}")
diff --git a/scripts/toolchains/ios.cmake b/scripts/toolchains/ios.cmake
index 5497117a3..b93cdbb8a 100644
--- a/scripts/toolchains/ios.cmake
+++ b/scripts/toolchains/ios.cmake
@@ -16,9 +16,11 @@ if(NOT _VCPKG_IOS_TOOLCHAIN)
             set(_vcpkg_ios_system_processor "arm")
             set(_vcpkg_ios_target_architecture "armv7")
         elseif("${arch}" STREQUAL "x64")
+            set(_vcpkg_ios_system_processor "x86_64")
             set(_vcpkg_ios_sysroot "iphonesimulator")
             set(_vcpkg_ios_target_architecture "x86_64")
         elseif("${arch}" STREQUAL "x86")
+            set(_vcpkg_ios_system_processor "i386")
             set(_vcpkg_ios_sysroot "iphonesimulator")
             set(_vcpkg_ios_target_architecture "i386")
         else()
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index e7e25d738..290ffb0d0 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -598,6 +598,10 @@ namespace vcpkg::Build
         {
             return m_paths.scripts / fs::u8path("toolchains/android.cmake");
         }
+        else if (cmake_system_name == "iOS")
+        {
+            return m_paths.scripts / fs::u8path("toolchains/ios.cmake");
+        }
         else if (cmake_system_name.empty() || cmake_system_name == "Windows" || cmake_system_name == "WindowsStore")
         {
             return m_paths.scripts / fs::u8path("toolchains/windows.cmake");

Note:
It would probably be best to only alter CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED when crosscompiling for iOS/tvOS/watchOS but it doesn't seem to hurt macOS compilation. Also it would be good to handle Ninja/Makefiles (as this is only for Xcode generator)

@alcroito
Copy link
Contributor Author

Will you open a pull request with your changes?

Also not sure what you mean with "would be good to handle Ninja / Makefiles". The code signing is already not present for those generators.

@christophe-calmejane
Copy link
Contributor

I won't be able to easily make a PR right now (these changes are on a completely other branch and I lack time) but I'll try to do so if I can find a bit of time (and nobody already did ^^).
You are right about code signing, but as I have a more complex toolchain than the default vcpkg one, when I generate for Ninja it also includes codesigning which I forgot about :)

@christophe-calmejane
Copy link
Contributor

I just edited the patch as I noticed a mistake in the openssl port update

@alcroito
Copy link
Contributor Author

Could you tell me how did you force vcpkg to use Xcode as the generator? Did you simply set CMAKE_GENERATOR env var?

I could probably create a PR with the general bits (so without boost and openssl)

Out of curiosity, is the toolchain you use for ninja + code signing available online somewhere?

@christophe-calmejane
Copy link
Contributor

It's part of a more complex toolchain I'm using and I'm currently trying to extract it to a reusable (more generic) toolchain.
I've already created some scripts that help leverage codesigning (cross platform mac/win) here https://github.com/christophe-calmejane/cmakeUtils . Not perfect but might be of some help somehow.

@alcroito
Copy link
Contributor Author

Pushed the non-xcode and non-port related changes to #12361

@christophe-calmejane
Copy link
Contributor

FYI, I opened a ticket on CMake bug tracker for an issue related to iOS cross compilation: https://gitlab.kitware.com/cmake/cmake/-/issues/20938

@christophe-calmejane
Copy link
Contributor

@alcroito Looks like boost is compiling, but it's actually not correct (it's always building for macOS instead of iphoneos or iphonesimulator). I tried to change boost-modular and boost-build packages, but it's not going anywhere and I'm running out of time.
From what I've seen it looks like a lot of parameters must be passed to b2, and probably elsewhere... not sure. The ports scripts have to be changed a lot to support the correct options.

@alcroito
Copy link
Contributor Author

That's usually the case with any port that doesn't use CMake as the meta-build tool, so not surprising. I've had similar issues with the Botan port, which uses it's own custom Python-based build system.

I expect once somebody really needs it, they will fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.