diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 931363c83..a41d48499 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -191,6 +191,7 @@ Properties on Targets /prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG /prop_tgt/INTERPROCEDURAL_OPTIMIZATION + /prop_tgt/IOS_INSTALL_COMBINED /prop_tgt/JOB_POOL_COMPILE /prop_tgt/JOB_POOL_LINK /prop_tgt/LABELS diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 211690050..3f4957283 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -257,6 +257,7 @@ Variables that Control the Build /variable/CMAKE_INSTALL_NAME_DIR /variable/CMAKE_INSTALL_RPATH /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH + /variable/CMAKE_IOS_INSTALL_COMBINED /variable/CMAKE_LANG_COMPILER_LAUNCHER /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE /variable/CMAKE_LANG_VISIBILITY_PRESET diff --git a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst new file mode 100644 index 000000000..59f67a7eb --- /dev/null +++ b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst @@ -0,0 +1,11 @@ +IOS_INSTALL_COMBINED +-------------------- + +Build a combined (device and simulator) target when installing. + +When this property is set to set to false (which is the default) then it will +either be built with the device SDK or the simulator SDK depending on the SDK +set. But if this property is set to true then the target will at install time +also be built for the corresponding SDK and combined into one library. + +This feature requires at least Xcode version 6. diff --git a/Help/release/dev/ios-universal.rst b/Help/release/dev/ios-universal.rst new file mode 100644 index 000000000..f96abede3 --- /dev/null +++ b/Help/release/dev/ios-universal.rst @@ -0,0 +1,7 @@ +ios-universal +------------- + +* When building for embedded Apple platforms like iOS CMake learned to build and + install combined targets which contain both a device and a simulator build. + This behavior can be enabled by setting the :prop_tgt:`IOS_INSTALL_COMBINED` + target property. diff --git a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst new file mode 100644 index 000000000..c5cb9b647 --- /dev/null +++ b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst @@ -0,0 +1,8 @@ +CMAKE_IOS_INSTALL_COMBINED +-------------------------- + +Default value for :prop_tgt:`IOS_INSTALL_COMBINED` of targets. + +This variable is used to initialize the :prop_tgt:`IOS_INSTALL_COMBINED` +property on all the targets. See that target property for additional +information. diff --git a/Modules/CMakeIOSInstallCombined.cmake b/Modules/CMakeIOSInstallCombined.cmake new file mode 100644 index 000000000..f052a3bf1 --- /dev/null +++ b/Modules/CMakeIOSInstallCombined.cmake @@ -0,0 +1,297 @@ + +#============================================================================= +# Copyright 2014-2015 Ruslan Baratov, Gregor Jasny +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Function to print messages of this module +function(_ios_install_combined_message) + message("[iOS combined] " ${ARGN}) +endfunction() + +# Get build settings for the current target/config/SDK by running +# `xcodebuild -sdk ... -showBuildSettings` and parsing it's output +function(_ios_install_combined_get_build_setting sdk variable resultvar) + if("${sdk}" STREQUAL "") + message(FATAL_ERROR "`sdk` is empty") + endif() + + if("${variable}" STREQUAL "") + message(FATAL_ERROR "`variable` is empty") + endif() + + if("${resultvar}" STREQUAL "") + message(FATAL_ERROR "`resultvar` is empty") + endif() + + set( + cmd + xcodebuild -showBuildSettings + -sdk "${sdk}" + -target "${CURRENT_TARGET}" + -config "${CURRENT_CONFIG}" + ) + + execute_process( + COMMAND ${cmd} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ) + + if(NOT result EQUAL 0) + message(FATAL_ERROR "Command failed (${result}): ${cmd}") + endif() + + if(NOT output MATCHES " ${variable} = ([^\n]*)") + message(FATAL_ERROR "${variable} not found.") + endif() + + set("${resultvar}" "${CMAKE_MATCH_1}" PARENT_SCOPE) +endfunction() + +# Get architectures of given SDK (iphonesimulator/iphoneos) +function(_ios_install_combined_get_valid_archs sdk resultvar) + cmake_policy(SET CMP0007 NEW) + + if("${resultvar}" STREQUAL "") + message(FATAL_ERROR "`resultvar` is empty") + endif() + + _ios_install_combined_get_build_setting("${sdk}" "VALID_ARCHS" valid_archs) + + separate_arguments(valid_archs) + list(REMOVE_ITEM valid_archs "") # remove empty elements + list(REMOVE_DUPLICATES valid_archs) + + set("${resultvar}" "${valid_archs}" PARENT_SCOPE) +endfunction() + +# Final target can contain more architectures that specified by SDK. This +# function will run 'lipo -info' and parse output. Result will be returned +# as a CMake list. +function(_ios_install_combined_get_real_archs filename resultvar) + set(cmd "${_lipo_path}" -info "${filename}") + execute_process( + COMMAND ${cmd} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + if(NOT result EQUAL 0) + message( + FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}" + ) + endif() + + if(NOT output MATCHES "(Architectures in the fat file: [^\n]+ are|Non-fat file: [^\n]+ is architecture): ([^\n]*)") + message(FATAL_ERROR "Could not detect architecture from: ${output}") + endif() + + separate_arguments(CMAKE_MATCH_2) + set(${resultvar} ${CMAKE_MATCH_2} PARENT_SCOPE) +endfunction() + +# Run build command for the given SDK +function(_ios_install_combined_build sdk) + if("${sdk}" STREQUAL "") + message(FATAL_ERROR "`sdk` is empty") + endif() + + _ios_install_combined_message("Build `${CURRENT_TARGET}` for `${sdk}`") + + execute_process( + COMMAND + "${CMAKE_COMMAND}" + --build + . + --target "${CURRENT_TARGET}" + --config ${CURRENT_CONFIG} + -- + -sdk "${sdk}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + RESULT_VARIABLE result + ) + + if(NOT result EQUAL 0) + message(FATAL_ERROR "Build failed") + endif() +endfunction() + +# Remove given architecture from file. This step needed only in rare cases +# when target was built in "unusual" way. Emit warning message. +function(_ios_install_combined_remove_arch lib arch) + _ios_install_combined_message( + "Warning! Unexpected architecture `${arch}` detected and will be removed " + "from file `${lib}`") + set(cmd "${_lipo_path}" -remove ${arch} -output ${lib} ${lib}) + execute_process( + COMMAND ${cmd} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + if(NOT result EQUAL 0) + message( + FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}" + ) + endif() +endfunction() + +# Check that 'lib' contains only 'archs' architectures (remove others). +function(_ios_install_combined_keep_archs lib archs) + _ios_install_combined_get_real_archs("${lib}" real_archs) + set(archs_to_remove ${real_archs}) + list(REMOVE_ITEM archs_to_remove ${archs}) + foreach(x ${archs_to_remove}) + _ios_install_combined_remove_arch("${lib}" "${x}") + endforeach() +endfunction() + +function(_ios_install_combined_detect_sdks this_sdk_var corr_sdk_var) + cmake_policy(SET CMP0057 NEW) + + set(this_sdk "$ENV{PLATFORM_NAME}") + if("${this_sdk}" STREQUAL "") + message(FATAL_ERROR "Environment variable PLATFORM_NAME is empty") + endif() + + set(all_platforms "$ENV{SUPPORTED_PLATFORMS}") + if("${all_platforms}" STREQUAL "") + message(FATAL_ERROR "Environment variable SUPPORTED_PLATFORMS is empty") + endif() + + separate_arguments(all_platforms) + if(NOT this_sdk IN_LIST all_platforms) + message(FATAL_ERROR "`${this_sdk}` not found in `${all_platforms}`") + endif() + + list(REMOVE_ITEM all_platforms "" "${this_sdk}") + list(LENGTH all_platforms all_platforms_length) + if(NOT all_platforms_length EQUAL 1) + message(FATAL_ERROR "Expected one element: ${all_platforms}") + endif() + + set(${this_sdk_var} "${this_sdk}" PARENT_SCOPE) + set(${corr_sdk_var} "${all_platforms}" PARENT_SCOPE) +endfunction() + +# Create combined binary for the given target. +# +# Preconditions: +# * Target already installed at ${destination} +# for the ${PLATFORM_NAME} platform +# +# This function will: +# * Run build for the lacking platform, i.e. opposite to the ${PLATFORM_NAME} +# * Fuse both libraries by running lipo +function(ios_install_combined target destination) + if("${target}" STREQUAL "") + message(FATAL_ERROR "`target` is empty") + endif() + + if("${destination}" STREQUAL "") + message(FATAL_ERROR "`destination` is empty") + endif() + + if(NOT IS_ABSOLUTE "${destination}") + message(FATAL_ERROR "`destination` is not absolute: ${destination}") + endif() + + if(IS_DIRECTORY "${destination}" OR IS_SYMLINK "${destination}") + message(FATAL_ERROR "`destination` is no regular file: ${destination}") + endif() + + if("${CMAKE_BINARY_DIR}" STREQUAL "") + message(FATAL_ERROR "`CMAKE_BINARY_DIR` is empty") + endif() + + if(NOT IS_DIRECTORY "${CMAKE_BINARY_DIR}") + message(FATAL_ERROR "Is not a directory: ${CMAKE_BINARY_DIR}") + endif() + + if("${CMAKE_INSTALL_CONFIG_NAME}" STREQUAL "") + message(FATAL_ERROR "CMAKE_INSTALL_CONFIG_NAME is empty") + endif() + + set(cmd xcrun -f lipo) + execute_process( + COMMAND ${cmd} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + if(NOT result EQUAL 0) + message( + FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}" + ) + endif() + set(_lipo_path ${output}) + + set(CURRENT_CONFIG "${CMAKE_INSTALL_CONFIG_NAME}") + set(CURRENT_TARGET "${target}") + + _ios_install_combined_message("Target: ${CURRENT_TARGET}") + _ios_install_combined_message("Config: ${CURRENT_CONFIG}") + _ios_install_combined_message("Destination: ${destination}") + + # Get SDKs + _ios_install_combined_detect_sdks(this_sdk corr_sdk) + + # Get architectures of the target + _ios_install_combined_get_valid_archs("${corr_sdk}" corr_valid_archs) + _ios_install_combined_get_valid_archs("${this_sdk}" this_valid_archs) + + # Return if there are no valid architectures for the SDK. + # (note that library already installed) + if("${corr_valid_archs}" STREQUAL "") + _ios_install_combined_message( + "No architectures detected for `${corr_sdk}` (skip)" + ) + return() + endif() + + # Trigger build of corresponding target + _ios_install_combined_build("${corr_sdk}") + + # Get location of the library in build directory + _ios_install_combined_get_build_setting( + "${corr_sdk}" "CONFIGURATION_BUILD_DIR" corr_build_dir) + _ios_install_combined_get_build_setting( + "${corr_sdk}" "EXECUTABLE_PATH" corr_executable_path) + set(corr "${corr_build_dir}/${corr_executable_path}") + + _ios_install_combined_keep_archs("${corr}" "${corr_valid_archs}") + _ios_install_combined_keep_archs("${destination}" "${this_valid_archs}") + + _ios_install_combined_message("Current: ${destination}") + _ios_install_combined_message("Corresponding: ${corr}") + + set(cmd "${_lipo_path}" -create ${corr} ${destination} -output ${destination}) + + execute_process( + COMMAND ${cmd} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + RESULT_VARIABLE result + ) + + if(NOT result EQUAL 0) + message(FATAL_ERROR "Command failed: ${cmd}") + endif() + + _ios_install_combined_message("Install done: ${destination}") +endfunction() diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index c6908c32a..1158a27d5 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -531,6 +531,7 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os, { this->AddInstallNamePatchRule(os, indent, config, file); this->AddChrpathPatchRule(os, indent, config, file); + this->AddUniversalInstallRule(os, indent, file); this->AddRanlibRule(os, indent, file); this->AddStripRule(os, indent, file); } @@ -867,3 +868,46 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os, os << indent << "execute_process(COMMAND \"" << ranlib << "\" \"" << toDestDirPath << "\")\n"; } + +//---------------------------------------------------------------------------- +void +cmInstallTargetGenerator +::AddUniversalInstallRule(std::ostream& os, + Indent const& indent, + const std::string& toDestDirPath) +{ + cmMakefile const* mf = this->Target->Target->GetMakefile(); + + if(!mf->PlatformIsAppleIos() || !mf->IsOn("XCODE")) + { + return; + } + + const char* xcodeVersion = mf->GetDefinition("XCODE_VERSION"); + if(!xcodeVersion || cmSystemTools::VersionCompareGreater("6", xcodeVersion)) + { + return; + } + + switch(this->Target->GetType()) + { + case cmState::EXECUTABLE: + case cmState::STATIC_LIBRARY: + case cmState::SHARED_LIBRARY: + case cmState::MODULE_LIBRARY: + break; + + default: + return; + } + + if(!this->Target->Target->GetPropertyAsBool("IOS_INSTALL_COMBINED")) + { + return; + } + + os << indent << "include(CMakeIOSInstallCombined)\n"; + os << indent << "ios_install_combined(" + << "\"" << this->Target->Target->GetName() << "\" " + << "\"" << toDestDirPath << "\")\n"; +} diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index ec89c05ea..18b313082 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -101,6 +101,8 @@ protected: const std::string& toDestDirPath); void AddRanlibRule(std::ostream& os, Indent const& indent, const std::string& toDestDirPath); + void AddUniversalInstallRule(std::ostream& os, Indent const& indent, + const std::string& toDestDirPath); std::string TargetName; cmGeneratorTarget* Target; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9ea1a34e6..1986e5fd3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -132,6 +132,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); + this->SetPropertyDefault("IOS_INSTALL_COMBINED", 0); this->SetPropertyDefault("AUTOMOC", 0); this->SetPropertyDefault("AUTOUIC", 0); this->SetPropertyDefault("AUTORCC", 0); diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index f89d62063..acc007580 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -94,3 +94,39 @@ if(NOT XCODE_VERSION VERSION_LESS 7) run_cmake(XcodeTbdStub) unset(RunCMake_TEST_OPTIONS) endif() + +if(NOT XCODE_VERSION VERSION_LESS 6) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombined-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install" + "-DCMAKE_IOS_INSTALL_COMBINED=YES") + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeIOSInstallCombined) + run_cmake_command(XcodeIOSInstallCombined-build ${CMAKE_COMMAND} --build .) + run_cmake_command(XcodeIOSInstallCombined-install ${CMAKE_COMMAND} --build . --target install) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_OPTIONS) + + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombinedPrune-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install" + "-DCMAKE_IOS_INSTALL_COMBINED=YES") + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeIOSInstallCombinedPrune) + run_cmake_command(XcodeIOSInstallCombinedPrune-build ${CMAKE_COMMAND} --build .) + run_cmake_command(XcodeIOSInstallCombinedPrune-install ${CMAKE_COMMAND} --build . --target install) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_OPTIONS) +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake new file mode 100644 index 000000000..a1c06718f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake @@ -0,0 +1,30 @@ +function(verify_architectures file) + execute_process( + COMMAND xcrun otool -vf ${RunCMake_TEST_BINARY_DIR}/_install/${file} + OUTPUT_VARIABLE otool_out + ERROR_VARIABLE otool_err + RESULT_VARIABLE otool_result) + if(NOT otool_result EQUAL "0") + message(SEND_ERROR "Could not retrieve fat headers: ${otool_err}") + return() + endif() + + string(REGEX MATCHALL "architecture [^ \n\t]+" architectures ${otool_out}) + string(REPLACE "architecture " "" actual "${architectures}") + list(SORT actual) + + set(expected arm64 armv7 i386 x86_64) + + if(NOT actual STREQUAL expected) + message(SEND_ERROR + "The actual library contains the architectures:\n ${actual} \n" + "which do not match expected ones:\n ${expected} \n" + "otool output:\n${otool_out}") + endif() +endfunction() + +verify_architectures(bin/foo_app.app/foo_app) +verify_architectures(lib/libfoo_static.a) +verify_architectures(lib/libfoo_shared.dylib) +verify_architectures(lib/foo_bundle.bundle/foo_bundle) +verify_architectures(lib/foo_framework.framework/foo_framework) diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake new file mode 100644 index 000000000..fc830b19e --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.3) + +project(IOSInstallCombined CXX) + +set(CMAKE_OSX_SYSROOT iphoneos) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf") +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") + +set(CMAKE_OSX_ARCHITECTURES "armv7;arm64;i386;x86_64") + +add_executable(foo_app MACOSX_BUNDLE main.cpp) +install(TARGETS foo_app BUNDLE DESTINATION bin) + +add_library(foo_static STATIC foo.cpp) +install(TARGETS foo_static ARCHIVE DESTINATION lib) + +add_library(foo_shared SHARED foo.cpp) +install(TARGETS foo_shared LIBRARY DESTINATION lib) + +add_library(foo_bundle MODULE foo.cpp) +set_target_properties(foo_bundle PROPERTIES BUNDLE TRUE) +install(TARGETS foo_bundle LIBRARY DESTINATION lib) + +add_library(foo_framework SHARED foo.cpp) +set_target_properties(foo_framework PROPERTIES FRAMEWORK TRUE) +install(TARGETS foo_framework FRAMEWORK DESTINATION lib) diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake new file mode 100644 index 000000000..83da17da7 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake @@ -0,0 +1,26 @@ +function(verify_architectures file) + execute_process( + COMMAND xcrun otool -vf ${RunCMake_TEST_BINARY_DIR}/_install/${file} + OUTPUT_VARIABLE otool_out + ERROR_VARIABLE otool_err + RESULT_VARIABLE otool_result) + if(NOT otool_result EQUAL "0") + message(SEND_ERROR "Could not retrieve fat headers: ${otool_err}") + return() + endif() + + string(REGEX MATCHALL "architecture [^ \n\t]+" architectures ${otool_out}) + string(REPLACE "architecture " "" actual "${architectures}") + list(SORT actual) + + set(expected armv7 x86_64) + + if(NOT actual STREQUAL expected) + message(SEND_ERROR + "The actual library contains the architectures:\n ${actual} \n" + "which do not match expected ones:\n ${expected} \n" + "otool output:\n${otool_out}") + endif() +endfunction() + +verify_architectures(lib/libfoo.dylib) diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt new file mode 100644 index 000000000..28edadc6b --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt @@ -0,0 +1,2 @@ +.*Unexpected architecture `i386` detected.* +.*Unexpected architecture `arm64` detected.* \ No newline at end of file diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake new file mode 100644 index 000000000..b47d3a597 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.3) + +project(XcodeIOSInstallCombinedPrune CXX) + +set(CMAKE_OSX_SYSROOT iphoneos) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf") + +add_library(foo SHARED foo.cpp) +install(TARGETS foo DESTINATION lib) + +add_library(baz SHARED foo.cpp) +set_target_properties( + foo baz + PROPERTIES + XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] armv7 + XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] armv7 + XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] x86_64 + XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] x86_64 +) + +add_library(boo SHARED foo.cpp) +set_target_properties( + boo + PROPERTIES + XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] arm64 + XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] arm64 + XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] i386 + XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] i386 +) + +add_custom_command( + TARGET foo + POST_BUILD + COMMAND lipo -create $ $ -output $ +) diff --git a/Tests/RunCMake/XcodeProject/main.cpp b/Tests/RunCMake/XcodeProject/main.cpp new file mode 100644 index 000000000..1695921f2 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/main.cpp @@ -0,0 +1,3 @@ +int main(int argc, const char * argv[]) { + return 0; +}