Skip to content

Fix escaping issue with multiple archs in VCPKG_TARGET_ARCHITECTURE to allow building for x64 and Apple Silicon at the same time #14932

@Deadpikle

Description

@Deadpikle

Summary

I'm wanting to build a binary for both x64 and Apple Silicon at the same time that is merged together for me rather than me having to run vcpkg 2x and do the extra binary merge work myself. This should be possible with CMake, however, vcpkg does not allow for this right now due to some problems.

Environment

  • Catalina -- macOS 10.15.7
  • Xcode 12.2
  • Fairly recent master (commit ecba240490afcc65e6ec07e49bf7f763a1a2b28b)

Description

I have the following triplet in a custom triplet file:

set(VCPKG_TARGET_ARCHITECTURE x86_64 arm64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)

set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
set(VCPKG_OSX_DEPLOYMENT_TARGET 10.10)

Note the different VCPKG_TARGET_ARCHITECTURE. Running a command such as ./vcpkg install libzip --triplet x64_arm64-osx --clean-after-build --debug results in this error:

CMake Error: The source directory "/Users/myname/Desktop/vcpkg-testing/vcpkg/buildtrees/detect_compiler/x64_arm64-osx-rel/arm64" does not exist.

The actual error is (edited to add newlines for easier reading here on GitHub)

-- Configuring x64_arm64-osx-rel
CMake Error at scripts/cmake/vcpkg_execute_required_process.cmake:108 (message):
    Command failed: /Users/myname/Desktop/vcpkg-testing/vcpkg/downloads/tools/cmake-3.18.4-osx/cmake-3.18.4
-Darwin-x86_64/CMake.app/Contents/bin/cmake /Users/myname/Desktop/vcpkg-testing/vcpkg/scripts/detect_compiler 
-DCMAKE_MAKE_PROGRAM=/Users/myname/Desktop/vcpkg-testing/vcpkg/downloads/tools/ninja-1.10.1-osx/ninja 
-DCMAKE_SYSTEM_NAME=Darwin 
-DBUILD_SHARED_LIBS=OFF 
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/Users/myname/Desktop/vcpkg-testing/vcpkg/scripts/toolchains/osx.cmake 
-DVCPKG_TARGET_TRIPLET=x64_arm64-osx 
-DVCPKG_SET_CHARSET_FLAG=ON 
-DVCPKG_PLATFORM_TOOLSET=external 
-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON 
-DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON 
-DCMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY=ON 
-DCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP=TRUE 
-DCMAKE_VERBOSE_MAKEFILE=ON 
-DVCPKG_APPLOCAL_DEPS=OFF 
-DCMAKE_TOOLCHAIN_FILE=/Users/myname/Desktop/vcpkg-testing/vcpkg/scripts/buildsystems/vcpkg.cmake 
-DCMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION=ON 
-DVCPKG_CXX_FLAGS= 
-DVCPKG_CXX_FLAGS_RELEASE= 
-DVCPKG_CXX_FLAGS_DEBUG= 
-DVCPKG_C_FLAGS= 
-DVCPKG_C_FLAGS_RELEASE= 
-DVCPKG_C_FLAGS_DEBUG= 
-DVCPKG_CRT_LINKAGE=dynamic 
-DVCPKG_LINKER_FLAGS= 
-DVCPKG_LINKER_FLAGS_RELEASE= 
-DVCPKG_LINKER_FLAGS_DEBUG= 
-DVCPKG_TARGET_ARCHITECTURE=x86_64 arm64 
-DCMAKE_INSTALL_LIBDIR:STRING=lib 
-DCMAKE_INSTALL_BINDIR:STRING=bin 
-D_VCPKG_ROOT_DIR=/Users/myname/Desktop/vcpkg-testing/vcpkg 
-D_VCPKG_INSTALLED_DIR=/Users/myname/Desktop/vcpkg-testing/vcpkg/installed 
-DVCPKG_MANIFEST_INSTALL=OFF 
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.10 -G Ninja 
-DCMAKE_BUILD_TYPE=Release 
-DCMAKE_INSTALL_PREFIX=/Users/myname/Desktop/vcpkg-testing/vcpkg/packages/detect_compiler_x64_arm64-osx
    Working Directory: /Users/myname/Desktop/vcpkg-testing/vcpkg/buildtrees/detect_compiler/x64_arm64-osx-rel
    Error code: 1
    See logs for more information:
      /Users/myname/Desktop/vcpkg-testing/vcpkg/buildtrees/detect_compiler/config-x64_arm64-osx-rel-err.log

Call Stack (most recent call first):
  scripts/cmake/vcpkg_configure_cmake.cmake:338 (vcpkg_execute_required_process)
  scripts/detect_compiler/portfile.cmake:18 (vcpkg_configure_cmake)
  scripts/ports.cmake:136 (include)

Note this part: -DVCPKG_TARGET_ARCHITECTURE=x86_64 arm64 -- this is likely why we are getting an error about an arm64 dir. This param is not being escaped properly.

Historical Context

I have this feature working in a fork. #12657 was a PR to fix these issues that was split into 4 subsequent PRs that also has more historical information. Three of those subsequent PRs were merged, and one was not (#12718 was not merged) due to me never finishing it because [reasons].

My working fork with this feature is available here: https://github.com/Deadpikle/vcpkg/tree/fix/osx-archs-attempt. Note that this requires Xcode 12.2+ to build for Apple Silicon and x64. However, my fork is quite old, and when trying to apply the same fixes to the latest master, things still don't work out, and I'm not sure why.

Proposed solution

I am guessing that fixing this problem is probably two-fold:

  1. Need to fix escaping issues so that -DVCPKG_TARGET_ARCHITECTURE is output properly
  2. Probably need to re-apply some of the adjustments from [vcpkg osx] Fix building for non-x86_64 archs on macOS (OSX) and fixes escapes for some params #12657 to get it all right, notably the setting of -DCMAKE_OSX_ARCHITECTURES to the contents of -DVCPKG_TARGET_ARCHITECTURE -- but this is just a guess on my part. (See note below on alternatives how this could just be done in the triplet)

Describe alternatives you've considered

In theory, you could probably use the x64-osx.cmake triplet and the arm64-osx.cmake triplet to build the raw libraries, then use some combination of lipo or something else to merge the libraries. This would look something like what this blog post describes or this SO post describes. However, having this capability built in to vcpkg is much easier and more convenient for end users. Plus, the escaping issue is an issue.

In addition, I could just do set(VCPKG_OSX_ARCHITECTURES x86_64 arm64) in the triplet and not worry about number 2 in the above solution, but it results in another something that looks like an escaping issue. set(VCPKG_TARGET_ARCHITECTURE x86_64;arm64) or set(VCPKG_OSX_ARCHITECTURES x86_64;arm64) does not rectify the issue -- it just results in more escaping problems down the road.

Thank you! 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    category:community-tripletA PR or issue related to community triplets not officially validated by the vcpkg team.category:vcpkg-bugThe issue is with the vcpkg system (including helper scripts in `scripts/cmake/`)category:vcpkg-featureThe issue is a new capability of the tool that doesn’t already exist and we haven’t committed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions