Skip to content

Commit

Permalink
Introduce split build for osx ports without universal builds
Browse files Browse the repository at this point in the history
Some ports (e.g. libpng) don't support building for multiple
architectures at the same time. For these ports, we can now use the
OSX_SPLIT_BUILD option, which will perform multiple builds (one for each
requested architecture) and then merge them into a universal binary when
the build is complete
  • Loading branch information
martijn-resolume committed Aug 1, 2022
1 parent 66045de commit 70bfa5a
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 22 deletions.
1 change: 1 addition & 0 deletions docs/maintainers/ports/vcpkg-cmake/vcpkg_cmake_install.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ vcpkg_cmake_install(
with additional parameters to set the `TARGET` to `install`,
and to set the `LOGFILE_ROOT` to `install` as well.


[`vcpkg_cmake_build()`]: vcpkg_cmake_build.md

## Examples:
Expand Down
2 changes: 1 addition & 1 deletion ports/vcpkg-cmake/vcpkg.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vcpkg-cmake",
"version-date": "2022-07-18",
"version-date": "2022-08-01",
"documentation": "https://vcpkg.io/en/docs/maintainers/ports/vcpkg-cmake.html",
"license": "MIT"
}
61 changes: 43 additions & 18 deletions ports/vcpkg-cmake/vcpkg_cmake_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,50 @@ function(vcpkg_cmake_build)
endif()
endif()

if(arg_DISABLE_PARALLEL)
vcpkg_execute_build_process(
COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${no_parallel_param}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_build_type}"
LOGNAME "${arg_LOGFILE_BASE}-${TARGET_TRIPLET}-${short_build_type}"
)
if (Z_VCPKG_OSX_SPLIT_BUILD)
foreach(OSX_ARCHITECTURE ${VCPKG_OSX_ARCHITECTURES})
if (arg_DISABLE_PARALLEL)
vcpkg_execute_build_process(
COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${no_parallel_param}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_build_type}-${OSX_ARCHITECTURE}"
LOGNAME "${arg_LOGFILE_BASE}-${TARGET_TRIPLET}-${short_build_ttype}-${OSX_ARCHITECTURE}"
)
else()
vcpkg_execute_build_process(
COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${parallel_param}
NO_PARALLEL_COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${no_parallel_param}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_build_type}-${OSX_ARCHITECTURE}"
LOGNAME "${arg_LOGFILE_BASE}-${TARGET_TRIPLET}-${short_build_type}-${OSX_ARCHITECTURE}"
)
endif()
endforeach()
else()
vcpkg_execute_build_process(
COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${parallel_param}
NO_PARALLEL_COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${no_parallel_param}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_build_type}"
LOGNAME "${arg_LOGFILE_BASE}-${TARGET_TRIPLET}-${short_build_type}"
)
if(arg_DISABLE_PARALLEL)
vcpkg_execute_build_process(
COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${no_parallel_param}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_build_type}"
LOGNAME "${arg_LOGFILE_BASE}-${TARGET_TRIPLET}-${short_build_type}"
)
else()
vcpkg_execute_build_process(
COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${parallel_param}
NO_PARALLEL_COMMAND
"${CMAKE_COMMAND}" --build . --config "${config}" ${target_param}
-- ${build_param} ${no_parallel_param}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_build_type}"
LOGNAME "${arg_LOGFILE_BASE}-${TARGET_TRIPLET}-${short_build_type}"
)
endif()
endif()

if(arg_ADD_BIN_TO_PATH)
Expand Down
87 changes: 85 additions & 2 deletions ports/vcpkg-cmake/vcpkg_cmake_configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endmacro()

function(vcpkg_cmake_configure)
cmake_parse_arguments(PARSE_ARGV 0 "arg"
"PREFER_NINJA;DISABLE_PARALLEL_CONFIGURE;WINDOWS_USE_MSBUILD;NO_CHARSET_FLAG;Z_CMAKE_GET_VARS_USAGE"
"PREFER_NINJA;DISABLE_PARALLEL_CONFIGURE;WINDOWS_USE_MSBUILD;NO_CHARSET_FLAG;Z_CMAKE_GET_VARS_USAGE;OSX_SPLIT_BUILD"
"SOURCE_PATH;GENERATOR;LOGFILE_BASE"
"OPTIONS;OPTIONS_DEBUG;OPTIONS_RELEASE;MAYBE_UNUSED_VARIABLES"
)
Expand Down Expand Up @@ -180,12 +180,28 @@ function(vcpkg_cmake_configure)
)

# Sets configuration variables for macOS builds
foreach(config_var IN ITEMS INSTALL_NAME_DIR OSX_DEPLOYMENT_TARGET OSX_SYSROOT OSX_ARCHITECTURES)
foreach(config_var IN ITEMS INSTALL_NAME_DIR OSX_DEPLOYMENT_TARGET OSX_SYSROOT)
if(DEFINED VCPKG_${config_var})
vcpkg_list(APPEND arg_OPTIONS "-DCMAKE_${config_var}=${VCPKG_${config_var}}")
endif()
endforeach()

# if a split build was requested we must perform two separate builds
# if - and only if - multiple architectures were passed
if (arg_OSX_SPLIT_BUILD)
list(LENGTH VCPKG_OSX_ARCHITECTURES ARCHITECTURE_LENGTH)
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND ARCHITECTURE_LENGTH GREATER_EQUAL "2")
set(Z_VCPKG_OSX_SPLIT_BUILD ON CACHE INTERNAL "split build per architecture")
endif()
endif()

# if we are not doing a split build we define the architectures, otherwise
# they will be defined individually for each separete split build
if (NOT Z_VCPKG_OSX_SPLIT_BUILD AND DEFINED VCPKG_OSX_ARCHITECTURES)
list(JOIN VCPKG_OSX_ARCHITECTURES "\;" JOINED_ARCHITECTURES)
list(APPEND arg_OPTIONS "-DCMAKE_OSX_ARCHITECTURES=${JOINED_ARCHITECTURES}")
endif()

# Allow overrides / additional configuration variables from triplets
if(DEFINED VCPKG_CMAKE_CONFIGURE_OPTIONS)
vcpkg_list(APPEND arg_OPTIONS ${VCPKG_CMAKE_CONFIGURE_OPTIONS})
Expand Down Expand Up @@ -245,6 +261,73 @@ function(vcpkg_cmake_configure)
vcpkg_list(APPEND config_logs
"${CURRENT_BUILDTREES_DIR}/${arg_LOGFILE_BASE}-out.log"
"${CURRENT_BUILDTREES_DIR}/${arg_LOGFILE_BASE}-err.log")
elseif(Z_VCPKG_OSX_SPLIT_BUILD)
foreach(OSX_ARCHITECTURE ${VCPKG_OSX_ARCHITECTURES})
file(REMOVE_RECURSE
"${build_dir_release}-${OSX_ARCHITECTURE}"
"${build_dir_debug}-${OSX_ARCHITECTURE}")
file(MAKE_DIRECTORY "${build_dir_release}-${OSX_ARCHITECTURE}")
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
file(MAKE_DIRECTORY "${build_dir_debug}-${OSX_ARCHITECTURE}")
endif()
endforeach()

# the first selected architecture is installed in the usual location
# (the packages dir), the others are installed into the buildtree
# because the package install would otherwise overwrite the generated
# libraries, after installation the binaries will be merged
set(OSX_SPLIT_BUILD_FIRST_ARCHITECTURE ON)

foreach(OSX_ARCHITECTURE ${VCPKG_OSX_ARCHITECTURES})
if (OSX_SPLIT_BUILD_FIRST_ARCHITECTURE)
set(OSX_SPLIT_BUILD_INSTALL_DIR_DEBUG "${CURRENT_PACKAGES_DIR}/debug")
set(OSX_SPLIT_BUILD_INSTALL_DIR_RELEASE "${CURRENT_PACKAGES_DIR}")
else()
set(OSX_SPLIT_BUILD_INSTALL_DIR_DEBUG "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${OSX_ARCHITECTURE}-dbg-install")
set(OSX_SPLIT_BUILD_INSTALL_DIR_RELEASE "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${OSX_ARCHITECTURE}-rel-install")
endif()

if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
message(STATUS "${configuring_message}-dbg (arch: ${OSX_ARCHITECTURE})")
vcpkg_execute_required_process(
COMMAND
"${CMAKE_COMMAND}" "${arg_SOURCE_PATH}"
-D CMAKE_OSX_ARCHITECTURES=${OSX_ARCHITECTURE}
${arg_OPTIONS}
${arg_OPTIONS_DEBUG}
-G "${generator}"
"-DCMAKE_BUILD_TYPE=Debug"
"-DCMAKE_INSTALL_PREFIX=${OSX_SPLIT_BUILD_INSTALL_DIR_DEBUG}"
WORKING_DIRECTORY "${build_dir_debug}-${OSX_ARCHITECTURE}"
LOGNAME "${arg_LOGFILE_BASE}-dbg-${OSX_ARCHITECTURE}"
)
list(APPEND config_logs
"${CURRENT_BUILDTREES_DIR}/${arg_LOGFILE_BASE}-dbg-${OSX_ARCHITECTURE}-out.log"
"${CURRENT_BUILDTREES_DIR}/${arg_LOGFILE_BASE}-dbg-${OSX_ARCHITECTURE}-err.log")
endif()

if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
message(STATUS "${configuring_message}-rel (arch: ${OSX_ARCHITECTURE})")
vcpkg_execute_required_process(
COMMAND
"${CMAKE_COMMAND}" "${arg_SOURCE_PATH}"
-D CMAKE_OSX_ARCHITECTURES=${OSX_ARCHITECTURE}
${arg_OPTIONS}
${arg_OPTIONS_RELEASE}
-G "${generator}"
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_INSTALL_PREFIX=${OSX_SPLIT_BUILD_INSTALL_DIR_RELEASE}"
WORKING_DIRECTORY "${build_dir_release}-${OSX_ARCHITECTURE}"
LOGNAME "${arg_LOGFILE_BASE}-rel-${OSX_ARCHITECTURE}"
)
list(APPEND config_logs
"${CURRENT_BUILDTREES_DIR}/${arg_LOGFILE_BASE}-rel-${OSX_ARCHITECTURE}-out.log"
"${CURRENT_BUILDTREES_DIR}/${arg_LOGFILE_BASE}-rel-${OSX_ARCHITECTURE}-err.log")
endif()

# first architecture now complete
set(OSX_SPLIT_BUILD_FIRST_ARCHITECTURE OFF)
endforeach()
else()
if(NOT DEFINED VCPKG_BUILD_TYPE OR "${VCPKG_BUILD_TYPE}" STREQUAL "debug")
message(STATUS "${configuring_message}-dbg")
Expand Down
64 changes: 64 additions & 0 deletions ports/vcpkg-cmake/vcpkg_cmake_install.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,68 @@ function(vcpkg_cmake_install)
LOGFILE_BASE install
TARGET install
)

# check whether a split build was requested and executed
if (Z_VCPKG_OSX_SPLIT_BUILD)
list(LENGTH VCPKG_OSX_ARCHITECTURES ARCHITECTURE_LENGTH)
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND ${ARCHITECTURE_LENGTH} GREATER 1)
# if we performed a split build, we'll need to zip those up
# using the lipo tool, start by looking that up
find_program(LIPO_EXECUTABLE lipo REQUIRED)

foreach(buildtype IN ITEMS debug release)
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL buildtype)
if(buildtype STREQUAL "debug")
set(SHORT_BUILD_TYPE "dbg")
set(PACKAGE_DIR_SUFFIX "/debug")
else()
set(SHORT_BUILD_TYPE "rel")
set(PACKAGE_DIR_SUFFIX "")
endif()

set(INSTALL_DIRECTORIES)

foreach(OSX_ARCHITECTURE ${VCPKG_OSX_ARCHITECTURES})
if (NOT INSTALL_DIRECTORIES)
set(INSTALL_DIRECTORY "${CURRENT_PACKAGES_DIR}${PACKAGE_DIR_SUFFIX}")
else()
set(INSTALL_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${OSX_ARCHITECTURE}-${SHORT_BUILD_TYPE}-install")
endif()

list(APPEND INSTALL_DIRECTORIES "${INSTALL_DIRECTORY}")
endforeach()

# note: we cannot glob the library files in a single operation, due to a cmake
# bug in file globbing, a pattern like "*.{a,dylib}" does not work.
# also note that we are using the _last_ directory set, which is inside the
# buildtree, and not the normal packages directory, since that would likely
# also contain other installed libraries
file(GLOB_RECURSE STATIC_LIBS RELATIVE "${INSTALL_DIRECTORY}" "${INSTALL_DIRECTORY}/lib/*.a")
file(GLOB_RECURSE SHARED_LIBS RELATIVE "${INSTALL_DIRECTORY}" "${INSTALL_DIRECTORY}/lib/*.dylib")
file(GLOB_RECURSE EXECUTABLES RELATIVE "${INSTALL_DIRECTORY}" "${INSTALL_DIRECTORY}/bin/*")

# filter out symlinks to get the real libraries to process
foreach (FOUND_LIBRARY ${STATIC_LIBS} ${SHARED_LIBS} ${EXECUTABLES})
if (NOT IS_SYMLINK "${INSTALL_DIRECTORY}/${FOUND_LIBRARY}")
# now build the command to join the files
set(LIPO_ARGUMENTS "-create" "-output" "${CURRENT_PACKAGES_DIR}${PACKAGE_DIR_SUFFIX}/${FOUND_LIBRARY}")

# add all architectures to the library
foreach (OSX_ARCHITECTURE ${VCPKG_OSX_ARCHITECTURES})
list(POP_FRONT INSTALL_DIRECTORIES ARCH_INSTALL_DIRECTORY)
list(APPEND LIPO_ARGUMENTS "-arch" "${OSX_ARCHITECTURE}" "${ARCH_INSTALL_DIRECTORY}/${FOUND_LIBRARY}")
endforeach()

# now join the found libraries
vcpkg_execute_required_process(
COMMAND ${LIPO_EXECUTABLE} ${LIPO_ARGUMENTS}
WORKING_DIRECTORY ${CURRENT_PACKAGES_DIR}
LOGNAME "lipo-${TARGET_TRIPLET}"
)
endif()
endforeach()
endif()
endforeach()
endif()
endif()
endfunction()
2 changes: 1 addition & 1 deletion versions/baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -7425,7 +7425,7 @@
"port-version": 0
},
"vcpkg-cmake": {
"baseline": "2022-07-18",
"baseline": "2022-08-01",
"port-version": 0
},
"vcpkg-cmake-config": {
Expand Down
5 changes: 5 additions & 0 deletions versions/v-/vcpkg-cmake.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"versions": [
{
"git-tree": "73b8a4a2a1220d2f3d167e552fcb617f5cfdf9cb",
"version-date": "2022-08-01",
"port-version": 0
},
{
"git-tree": "a7b618b7782f3c841d7fd2d84a6ba3619815362a",
"version-date": "2022-07-18",
Expand Down

0 comments on commit 70bfa5a

Please sign in to comment.