On 24-Oct-15 02:56, Gregor Jasny wrote:
On 08/10/15 02:37, Ruslan Baratov wrote:
export CORRESPONDING_DEVICE_PLATFORM_NAME=iphoneos
export CORRESPONDING_DEVICE_SDK_NAME=iphoneos9.0
export SDK_NAME=iphonesimulator9.0
Could you use those variables to avoid hardcoding iphoneos/simulator in
the module?
I see CORRESPONDING_*_SDK_NAME variables in Xcode 7.0 but not in 6.4.
At least in Xcode 6.2 I the following variable defined:
SUPPORTED_PLATFORMS="iphonesimulator iphoneos"
It also seems to be set with Xcode 7.1
SUPPORTED_PLATFORMS="watchsimulator watchos"
SUPPORTED_PLATFORMS="appletvos appletvsimulator"
Implemented. Now module use environment variables PLATFORM_NAME and
SUPPORTED_PLATFORMS to determine current SDK and corresponding SDK.
Same for the architectures: In the end the user (or the Xcode default)
sets a list of VALID_ARCHS for device and simulator. Maybe you could use
this for filtering.
Just for the record hardcoded architectures was already removed by
previous patch. Also I think we can't use VALID_ARCHS value since it's
possible to have more architectures in installed library (`lipo -info`
used for now).
Ruslo
>From 94aa1b8b2d936215f32454769cf11244bb7a0393 Mon Sep 17 00:00:00 2001
From: Ruslan Baratov <ruslan_bara...@yahoo.com>
Date: Thu, 8 Oct 2015 03:09:34 +0300
Subject: [PATCH 1/3] Get target name for universal iOS library install
Add method GetTargetNameForUniversalIosInstall to cmInstallTargetGenerator.
This method will return target name if:
* Platform is iOS
* Generator is Xcode
* Target is library
* CMake variable CMAKE_IOS_INSTALL_UNIVERSAL_LIBS or target property
IOS_INSTALL_UNIVERSAL_LIBS is ON
Otherwise an empty string will be returned.
---
Source/cmInstallTargetGenerator.cxx | 42 +++++++++++++++++++++++++++++++++++++
Source/cmInstallTargetGenerator.h | 5 +++++
2 files changed, 47 insertions(+)
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index a97cc5f..e3a0830 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -862,3 +862,45 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
os << indent << "execute_process(COMMAND \""
<< ranlib << "\" \"" << toDestDirPath << "\")\n";
}
+
+std::string
+cmInstallTargetGenerator
+::GetTargetNameForUniversalIosInstall(cmInstallType type) const
+{
+ cmMakefile const* mf = this->Target->Target->GetMakefile();
+ if(!mf->PlatformIsAppleIos())
+ {
+ return "";
+ }
+
+ switch(type)
+ {
+ case cmInstallType_STATIC_LIBRARY:
+ case cmInstallType_SHARED_LIBRARY:
+ case cmInstallType_MODULE_LIBRARY:
+ break;
+ default:
+ return "";
+ }
+
+ const char* xcode = mf->GetDefinition("XCODE");
+ if(cmSystemTools::IsOff(xcode))
+ {
+ // Xcode only
+ return "";
+ }
+
+ if(this->Target->Target->GetPropertyAsBool("IOS_INSTALL_UNIVERSAL_LIBS"))
+ {
+ return this->Target->GetName();
+ }
+
+ const char* var = "CMAKE_IOS_INSTALL_UNIVERSAL_LIBS";
+ const char* flag = mf->GetDefinition(var);
+ if (cmSystemTools::IsOff(flag))
+ {
+ return "";
+ }
+
+ return this->Target->GetName();
+}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index ec89c05..10a1be4 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -108,6 +108,11 @@ protected:
NamelinkModeType NamelinkMode;
bool ImportLibrary;
bool Optional;
+
+ private:
+ /** Get target name for installing universal iOS library. If target is not
+ an iOS library or universal build is disabled return empty string. */
+ std::string GetTargetNameForUniversalIosInstall(cmInstallType type) const;
};
#endif
--
1.9.3 (Apple Git-50)
>From e3881e1fe5de124eda1082044f2c9208f528a530 Mon Sep 17 00:00:00 2001
From: Ruslan Baratov <ruslan_bara...@yahoo.com>
Date: Sun, 25 Oct 2015 19:38:08 +0600
Subject: [PATCH 2/3] Make module for universal iOS library install
Add CMake module with function `install_universal_ios_library`.
Target name and destination passed to the function. This function will be run
after library installed: will trigger additional build instructions for missing
platform and fuse libraries into universal in destination directory.
Module designed to be used in `cmake_install.cmake` script.
---
Modules/install_universal_ios_library.cmake | 336 ++++++++++++++++++++++++++++
1 file changed, 336 insertions(+)
create mode 100644 Modules/install_universal_ios_library.cmake
diff --git a/Modules/install_universal_ios_library.cmake b/Modules/install_universal_ios_library.cmake
new file mode 100644
index 0000000..5499012
--- /dev/null
+++ b/Modules/install_universal_ios_library.cmake
@@ -0,0 +1,336 @@
+#=============================================================================
+# Copyright 2014-2015 Ruslan Baratov
+#
+# 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(install_universal_ios_message str)
+ message("[iOS universal] ${str}")
+endfunction()
+
+# Get build settings for the current target/config/SDK by running
+# `xcodebuild -sdk ... -showBuildSettings` and parsing it's output
+function(install_universal_ios_get 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()
+
+ string(REPLACE "\n" ";" output "${output}")
+
+ set(var_pattern " ${variable} = ")
+ string(LENGTH "${var_pattern}" var_pattern_len)
+
+ set(result "")
+ foreach(x ${output})
+ string(FIND "${x}" "${var_pattern}" index)
+ if(index EQUAL 0)
+ if(NOT "${result}" STREQUAL "")
+ message(FATAL_ERROR "${variable} already found: ${result}")
+ endif()
+ string(SUBSTRING "${x}" "${var_pattern_len}" -1 result)
+ if("${result}" STREQUAL "")
+ message(FATAL_ERROR "Empty value of variable: ${variable}")
+ endif()
+ endif()
+ endforeach()
+
+ set("${resultvar}" "${result}" PARENT_SCOPE)
+endfunction()
+
+# Get architectures of given SDK (iphonesimulator/iphoneos)
+function(install_universal_ios_get_archs sdk resultvar)
+ cmake_policy(SET CMP0007 NEW)
+
+ if("${resultvar}" STREQUAL "")
+ message(FATAL_ERROR "`resultvar` is empty")
+ endif()
+
+ install_universal_ios_get("${sdk}" "VALID_ARCHS" valid_archs)
+
+ string(REPLACE " " ";" valid_archs "${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(install_universal_ios_get_real_archs filename resultvar)
+ set(cmd lipo -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()
+
+ # 'lipo -info' succeeded, check file has only one architecture
+ string(
+ REGEX
+ REPLACE ".*Non-fat file: .* is architecture: " ""
+ single_arch
+ "${output}"
+ )
+ if(NOT "${single_arch}" STREQUAL "${output}")
+ # REGEX matches
+ string(REPLACE " " ";" single_arch "${single_arch}")
+ list(LENGTH single_arch len)
+ if(NOT len EQUAL 1)
+ message(FATAL_ERROR "Expected one architecture for output: ${output}")
+ endif()
+ set(${resultvar} "${single_arch}" PARENT_SCOPE)
+ return()
+ endif()
+
+ # 'lipo -info' succeeded, check file has multiple architectures
+ string(
+ REGEX
+ REPLACE "^Architectures in the fat file: .* are: " ""
+ architectures
+ "${output}"
+ )
+ if("${architectures}" STREQUAL "${output}")
+ # REGEX doesn't match
+ message(FATAL_ERROR "Unexpected output: ${output}")
+ endif()
+ string(REPLACE " " ";" architectures "${architectures}")
+ list(LENGTH architectures len)
+ if(len EQUAL 0 OR len EQUAL 1)
+ message(FATAL_ERROR "Expected >1 architecture for output: ${output}")
+ endif()
+ set(${resultvar} "${architectures}" PARENT_SCOPE)
+endfunction()
+
+# Run build command for the given SDK
+function(install_universal_ios_build sdk)
+ if("${sdk}" STREQUAL "")
+ message(FATAL_ERROR "`sdk` is empty")
+ endif()
+
+ install_universal_ios_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(install_universal_ios_remove_arch lib arch)
+ set(msg_p1 "Warning! Unexpected architecture `${arch}` detected")
+ set(msg_p2 "and will be removed from file `${lib}`")
+ install_universal_ios_message("${msg_p1} ${msg_p2}")
+ set(cmd lipo -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(install_universal_ios_keep_archs lib archs)
+ install_universal_ios_get_real_archs("${lib}" real_archs)
+ set(archs_to_remove ${real_archs})
+ list(REMOVE_ITEM archs_to_remove ${archs})
+ foreach(x ${archs_to_remove})
+ install_universal_ios_remove_arch("${lib}" "${x}")
+ endforeach()
+endfunction()
+
+# Create universal library for the given target.
+#
+# Preconditions:
+# * Library already installed to ${destination} directory
+# 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 -create ${src} ${dst} -output ${dst}`
+# src: library that was just built
+# dst: installed library
+function(install_universal_ios_library 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(NOT IS_DIRECTORY "${destination}")
+ message(FATAL_ERROR "`destination` is not absolute: ${destination}")
+ endif()
+
+ if(NOT EXISTS "${destination}")
+ message(FATAL_ERROR "`destination` not exists: ${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(NOT EXISTS "${CMAKE_BINARY_DIR}")
+ message(FATAL_ERROR "Not exists: ${CMAKE_BINARY_DIR}")
+ endif()
+
+ if("${CMAKE_INSTALL_CONFIG_NAME}" STREQUAL "")
+ message(FATAL_ERROR "CMAKE_INSTALL_CONFIG_NAME is empty")
+ endif()
+
+ set(platform_name "$ENV{PLATFORM_NAME}")
+ if("${platform_name}" 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()
+
+ set(this_sdk "${platform_name}")
+
+ string(REPLACE " " ";" corr_sdk "${all_platforms}")
+ list(FIND corr_sdk "${this_sdk}" this_sdk_index)
+ if(this_sdk_index EQUAL -1)
+ message(FATAL_ERROR "`${this_sdk}` not found in `${corr_sdk}`")
+ endif()
+
+ list(REMOVE_ITEM corr_sdk "" "${this_sdk}")
+ list(LENGTH corr_sdk corr_sdk_length)
+ if(NOT corr_sdk_length EQUAL 1)
+ message(FATAL_ERROR "Expected one element: ${corr_sdk}")
+ endif()
+
+ set(CURRENT_CONFIG "${CMAKE_INSTALL_CONFIG_NAME}")
+ set(CURRENT_TARGET "${target}")
+
+ install_universal_ios_message("Target: ${CURRENT_TARGET}")
+ install_universal_ios_message("Config: ${CURRENT_CONFIG}")
+ install_universal_ios_message("Destination: ${destination}")
+
+ # Get architectures of the target
+ install_universal_ios_get_archs("${corr_sdk}" corr_archs)
+ install_universal_ios_get_archs("${this_sdk}" this_archs)
+
+ # Return if there are no valid architectures for the SDK.
+ # (note that library already installed)
+ if("${corr_archs}" STREQUAL "")
+ install_universal_ios_message(
+ "No architectures detected for `${corr_sdk}` (skip)"
+ )
+ return()
+ endif()
+
+ # Get location of the library in build directory
+ install_universal_ios_get("${corr_sdk}" "CODESIGNING_FOLDER_PATH" src)
+
+ # Library output name
+ install_universal_ios_get("${corr_sdk}" "EXECUTABLE_NAME" corr_libname)
+ install_universal_ios_get("${this_sdk}" "EXECUTABLE_NAME" this_libname)
+
+ if("${corr_libname}" STREQUAL "${this_libname}")
+ set(libname "${corr_libname}")
+ else()
+ message(FATAL_ERROR "Library names differs: ${corr_libname} ${this_libname}")
+ endif()
+
+ set(dst "${destination}/${libname}")
+
+ install_universal_ios_build("${corr_sdk}")
+
+ install_universal_ios_keep_archs("${src}" "${corr_archs}")
+ install_universal_ios_keep_archs("${dst}" "${this_archs}")
+
+ install_universal_ios_message("Current: ${dst}")
+ install_universal_ios_message("Corresponding: ${src}")
+
+ set(cmd lipo -create ${src} ${dst} -output ${dst})
+
+ execute_process(
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ RESULT_VARIABLE result
+ )
+
+ if(NOT result EQUAL 0)
+ message(FATAL_ERROR "Command failed: ${cmd}")
+ endif()
+
+ install_universal_ios_message("Install done: ${dst}")
+endfunction()
--
1.9.3 (Apple Git-50)
>From 046ddd57102efb8b2e031fddc8ea00725ba02034 Mon Sep 17 00:00:00 2001
From: Ruslan Baratov <ruslan_bara...@yahoo.com>
Date: Thu, 8 Oct 2015 03:13:57 +0300
Subject: [PATCH 3/3] Universal iOS library install
Run `install_universal_ios_library` function in `cmake_install.cmake` script if
`GetTargetNameForUniversalIosInstall` returns non-empty target name.
---
Source/cmInstallGenerator.cxx | 10 +++++++++-
Source/cmInstallGenerator.h | 3 ++-
Source/cmInstallTargetGenerator.cxx | 2 +-
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index 2e1c5f0..5c2cd21 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -45,7 +45,8 @@ void cmInstallGenerator
const char* permissions_dir /* = 0 */,
const char* rename /* = 0 */,
const char* literal_args /* = 0 */,
- Indent const& indent
+ Indent const& indent,
+ std::string target_name_for_universal_ios_install
)
{
// Use the FILE command to install the file.
@@ -142,6 +143,13 @@ void cmInstallGenerator
os << literal_args;
}
os << ")\n";
+ if(!target_name_for_universal_ios_install.empty())
+ {
+ os << indent << "include(install_universal_ios_library)\n";
+ os << indent << "install_universal_ios_library(";
+ os << "\"" << target_name_for_universal_ios_install << "\" ";
+ os << "\"" << absDest << "\")\n";
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index b8e5b53..ee10b0c 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -49,7 +49,8 @@ public:
const char* permissions_dir = 0,
const char* rename = 0,
const char* literal_args = 0,
- Indent const& indent = Indent()
+ Indent const& indent = Indent(),
+ std::string target_name_for_universal_ios_install = ""
);
/** Get the install destination as it should appear in the
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index e3a0830..c0a632d 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -337,7 +337,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
type, filesFrom, optional,
this->FilePermissions.c_str(), no_dir_permissions,
no_rename, literal_args.c_str(),
- indent);
+ indent, this->GetTargetNameForUniversalIosInstall(type));
// Add post-installation tweaks.
this->AddTweak(os, indent, config, filesTo,
--
1.9.3 (Apple Git-50)
--
Powered by www.kitware.com
Please keep messages on-topic and check the CMake FAQ at:
http://www.cmake.org/Wiki/CMake_FAQ
Kitware offers various services to support the CMake community. For more
information on each offering, please visit:
CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers