From e3fc2899c89fb075a695d6140eaadf11db85d96c Mon Sep 17 00:00:00 2001 From: Ruslan Baratov Date: Mon, 14 Mar 2016 17:27:53 +0700 Subject: [PATCH] Fix iOS combined feature for single architecture targets If list of valid target architectures is empty for given SDK then there will be no VALID_ARCHS build setting returned by Xcode. Return "" (empty string) explicitly in this case. This may happens if CMAKE_IOS_INSTALL_COMBINED is ON but only one architecture used in target. --- Modules/CMakeIOSInstallCombined.cmake | 12 ++++++++- .../RunCMake/XcodeProject/RunCMakeTest.cmake | 20 +++++++++++++++ ...tallCombinedSingleArch-install-check.cmake | 25 +++++++++++++++++++ .../XcodeIOSInstallCombinedSingleArch.cmake | 19 ++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake create mode 100644 Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake diff --git a/Modules/CMakeIOSInstallCombined.cmake b/Modules/CMakeIOSInstallCombined.cmake index f052a3bf1..1256f563e 100644 --- a/Modules/CMakeIOSInstallCombined.cmake +++ b/Modules/CMakeIOSInstallCombined.cmake @@ -52,7 +52,14 @@ function(_ios_install_combined_get_build_setting sdk variable resultvar) endif() if(NOT output MATCHES " ${variable} = ([^\n]*)") - message(FATAL_ERROR "${variable} not found.") + if("${variable}" STREQUAL "VALID_ARCHS") + # VALID_ARCHS may be unset by user for given SDK + # (e.g. for build without simulator). + set("${resultvar}" "" PARENT_SCOPE) + return() + else() + message(FATAL_ERROR "${variable} not found.") + endif() endif() set("${resultvar}" "${CMAKE_MATCH_1}" PARENT_SCOPE) @@ -72,6 +79,9 @@ function(_ios_install_combined_get_valid_archs sdk resultvar) list(REMOVE_ITEM valid_archs "") # remove empty elements list(REMOVE_DUPLICATES valid_archs) + string(REPLACE ";" " " printable "${valid_archs}") + _ios_install_combined_message("Architectures (${sdk}): ${printable}") + set("${resultvar}" "${valid_archs}" PARENT_SCOPE) endfunction() diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 395c74b30..b77d5d40e 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -97,6 +97,7 @@ if(NOT XCODE_VERSION VERSION_LESS 7) endif() if(NOT XCODE_VERSION VERSION_LESS 6) + # XcodeIOSInstallCombined set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombined-build) set(RunCMake_TEST_NO_CLEAN 1) set(RunCMake_TEST_OPTIONS @@ -114,6 +115,7 @@ if(NOT XCODE_VERSION VERSION_LESS 6) unset(RunCMake_TEST_NO_CLEAN) unset(RunCMake_TEST_OPTIONS) + # XcodeIOSInstallCombinedPrune set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombinedPrune-build) set(RunCMake_TEST_NO_CLEAN 1) set(RunCMake_TEST_OPTIONS @@ -130,4 +132,22 @@ if(NOT XCODE_VERSION VERSION_LESS 6) unset(RunCMake_TEST_BINARY_DIR) unset(RunCMake_TEST_NO_CLEAN) unset(RunCMake_TEST_OPTIONS) + + # XcodeIOSInstallCombinedSingleArch + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombinedSingleArch-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(XcodeIOSInstallCombinedSingleArch) + run_cmake_command(XcodeIOSInstallCombinedSingleArch-build ${CMAKE_COMMAND} --build .) + run_cmake_command(XcodeIOSInstallCombinedSingleArch-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/XcodeIOSInstallCombinedSingleArch-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake new file mode 100644 index 000000000..3c11ae0ee --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake @@ -0,0 +1,25 @@ +function(verify_architecture file) + execute_process( + COMMAND xcrun lipo -info ${RunCMake_TEST_BINARY_DIR}/_install/${file} + OUTPUT_VARIABLE lipo_out + ERROR_VARIABLE lipo_err + RESULT_VARIABLE lipo_result) + if(NOT lipo_result EQUAL "0") + message(SEND_ERROR "lipo -info failed: ${lipo_err}") + return() + endif() + + string(REGEX MATCHALL "is architecture: [^ \n\t]+" architecture "${lipo_out}") + string(REGEX REPLACE "is architecture: " "" actual "${architecture}") + + set(expected armv7) + + if(NOT actual STREQUAL expected) + message(SEND_ERROR + "The actual library architecture:\n ${actual} \n" + "which do not match expected ones:\n ${expected} \n" + "lipo output:\n${lipo_out}") + endif() +endfunction() + +verify_architecture(lib/libfoo.dylib) diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake new file mode 100644 index 000000000..4b5e7ce36 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.3) + +project(XcodeIOSInstallCombinedSingleArch 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) + +set_target_properties( + foo + PROPERTIES + XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] armv7 + XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] armv7 + XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "" + XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "" +)