From 744e6c497c01cb3a3129ca66d1cabfa83e17dbd4 Mon Sep 17 00:00:00 2001 From: Gregor Jasny Date: Tue, 18 Aug 2015 21:30:54 +0200 Subject: Fix iOS Bundle layouts (#15669) In contrast to Mac OS X App bundle layout the iOS one lacks the Contents/MacOSX structure. See also the Bundle Structures documentation in Mac Developer Library: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html For now detect iOS targets by checking the SDK name/path. --- Source/cmGeneratorTarget.cxx | 30 +++++++++++------ Source/cmMakefile.cxx | 12 +++++++ Source/cmMakefile.h | 3 ++ Tests/RunCMake/XcodeProject/RunCMakeTest.cmake | 32 ++++++++++++++++++ Tests/RunCMake/XcodeProject/XcodeBundles.cmake | 46 ++++++++++++++++++++++++++ Tests/RunCMake/XcodeProject/main.m | 3 ++ 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 Tests/RunCMake/XcodeProject/XcodeBundles.cmake create mode 100644 Tests/RunCMake/XcodeProject/main.m diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 299c112..b9f78c6 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -951,9 +951,13 @@ cmGeneratorTarget::GetAppBundleDirectory(const std::string& config, bool contentOnly) const { std::string fpath = this->GetFullName(config, false); - fpath += ".app/Contents"; - if(!contentOnly) - fpath += "/MacOS"; + fpath += ".app"; + if(!this->Makefile->PlatformIsAppleIos()) + { + fpath += "/Contents"; + if(!contentOnly) + fpath += "/MacOS"; + } return fpath; } @@ -985,9 +989,12 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config, } } fpath += ext; - fpath += "/Contents"; - if(!contentOnly) - fpath += "/MacOS"; + if(!this->Makefile->PlatformIsAppleIos()) + { + fpath += "/Contents"; + if(!contentOnly) + fpath += "/MacOS"; + } return fpath; } @@ -999,7 +1006,7 @@ cmGeneratorTarget::GetFrameworkDirectory(const std::string& config, std::string fpath; fpath += this->GetOutputName(config, false); fpath += ".framework"; - if(!rootDir) + if(!rootDir && !this->Makefile->PlatformIsAppleIos()) { fpath += "/Versions/"; fpath += this->Target->GetFrameworkVersion(); @@ -2146,9 +2153,12 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name, if(this->Target->IsFrameworkOnApple()) { realName = prefix; - realName += "Versions/"; - realName += this->Target->GetFrameworkVersion(); - realName += "/"; + if(!this->Makefile->PlatformIsAppleIos()) + { + realName += "Versions/"; + realName += this->Target->GetFrameworkVersion(); + realName += "/"; + } realName += base; soName = realName; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 85bc493..6e43b52 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2529,6 +2529,18 @@ bool cmMakefile::PlatformIs64Bit() const return false; } +bool cmMakefile::PlatformIsAppleIos() const +{ + std::string sdkRoot; + sdkRoot = this->GetSafeDefinition("CMAKE_OSX_SYSROOT"); + sdkRoot = cmSystemTools::LowerCase(sdkRoot); + + return sdkRoot.find("iphoneos") == 0 || + sdkRoot.find("/iphoneos") != std::string::npos || + sdkRoot.find("iphonesimulator") == 0 || + sdkRoot.find("/iphonesimulator") != std::string::npos; +} + const char* cmMakefile::GetSONameFlag(const std::string& language) const { std::string name = "CMAKE_SHARED_LIBRARY_SONAME"; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1c4da00..9f455cc 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -490,6 +490,9 @@ public: /** Return whether the target platform is 64-bit. */ bool PlatformIs64Bit() const; + /** Return whether the target platform is Apple iOS. */ + bool PlatformIsAppleIos() const; + /** Retrieve soname flag for the specified language if supported */ const char* GetSONameFlag(const std::string& language) const; diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index b7de614..ef81739 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -7,3 +7,35 @@ run_cmake(XcodeObjectNeedsQuote) if (NOT XCODE_VERSION VERSION_LESS 6) run_cmake(XcodePlatformFrameworks) endif() + +# Use a single build tree for a few tests without cleaning. + +if(NOT XCODE_VERSION VERSION_LESS 5) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesOSX-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_OPTIONS "-DTEST_IOS=OFF") + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeBundles) + run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_OPTIONS) + + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesIOS-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_OPTIONS "-DTEST_IOS=ON") + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeBundles) + run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_OPTIONS) +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake new file mode 100644 index 0000000..d5cb51f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake @@ -0,0 +1,46 @@ +# check if Xcode and CMake have the same understanding of Bundle layout + +cmake_minimum_required(VERSION 3.3) +enable_language(C) + +if(TEST_IOS) + set(CMAKE_OSX_SYSROOT iphoneos) + set(CMAKE_OSX_ARCHITECTURES "armv7") + set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos;-iphonesimulator") + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") +endif(TEST_IOS) + +# App Bundle + +add_executable(AppBundle MACOSX_BUNDLE main.m) + +add_custom_target(AppBundleTest ALL + COMMAND ${CMAKE_COMMAND} -E copy + "$" "$.old") + +add_dependencies(AppBundleTest AppBundle) + +# Framework (not supported for iOS on Xcode < 6) + +if(NOT TEST_IOS OR NOT XCODE_VERSION VERSION_LESS 6) + add_library(Framework SHARED main.c) + set_target_properties(Framework PROPERTIES FRAMEWORK TRUE) + + add_custom_target(FrameworkTest ALL + COMMAND ${CMAKE_COMMAND} -E copy + "$" "$.old") + + add_dependencies(FrameworkTest Framework) +endif() + +# Bundle + +add_library(Bundle MODULE main.c) +set_target_properties(Bundle PROPERTIES BUNDLE TRUE) + +add_custom_target(BundleTest ALL + COMMAND ${CMAKE_COMMAND} -E copy + "$" "$.old") + +add_dependencies(BundleTest Bundle) diff --git a/Tests/RunCMake/XcodeProject/main.m b/Tests/RunCMake/XcodeProject/main.m new file mode 100644 index 0000000..6dc190a --- /dev/null +++ b/Tests/RunCMake/XcodeProject/main.m @@ -0,0 +1,3 @@ +int main(int argc, const char * argv[]) { + return 1; +} -- cgit v0.12