summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2021-04-14 18:16:44 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2021-04-19 20:30:45 +0200
commit4d838dae5a821e9e5f013ba1d5a494ece1b5180e (patch)
treeb02a79358b07649abd58710885f7c113f91d3ee1
parentb25eb6e0bd1e3b91c44dc4892d529b95c8677889 (diff)
CMake: Generate better Xcode iOS projects
Add an iOS specific plist file like we do for macOS. If the user hasn't specified a bundle identifier or a development team id, do what qmake does and query the Xcode preferences file to pre-populate those if possible. This allows running cmake -GXcode ./foo on a Qt example project and building it with xcodebuild on the command line without having to go through the IDE to set a development team id or modifying the example project to add a product bundle identifier. Note that the change assumes that the development team id has been previously set / configured via Xcode. If no such id is found, then the value will not be set and the user will still have to specify it either in the project file or via the Xcode UI after the project has been generated. Amends 3a2fa3fec5a43d30f1a93a8e89e2973f23ee4ef3 Pick-to: 6.1 Change-Id: Iaab4e57de72c9877fb9035d28f9a879b2c91a33c Reviewed-by: Cristian Adam <cristian.adam@qt.io>
-rw-r--r--CMakeLists.txt3
-rw-r--r--cmake/QtBaseGlobalTargets.cmake5
-rw-r--r--cmake/QtConfig.cmake.in3
-rw-r--r--cmake/ios/MacOSXBundleInfo.plist.in46
-rw-r--r--src/corelib/Qt6CoreMacros.cmake138
5 files changed, 195 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0ea57bdf29..76c08084d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,6 +50,9 @@ if(NOT QT_BUILD_STANDALONE_TESTS)
if(MACOS)
# Add module directory to pick up custom Info.plist template
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos")
+ elseif(IOS)
+ # Add module directory to pick up custom Info.plist template
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/ios")
endif()
## Find the build internals package.
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 23a2dfbcf4..df0be95510 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -253,6 +253,11 @@ if(MACOS)
cmake/macos/MacOSXBundleInfo.plist.in
DESTINATION "${__GlobalConfig_install_dir}/macos"
)
+elseif(IOS)
+ qt_copy_or_install(FILES
+ cmake/ios/MacOSXBundleInfo.plist.in
+ DESTINATION "${__GlobalConfig_install_dir}/ios"
+ )
endif()
# Install CI support files to libexec.
diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in
index 00121013b2..451d4191a7 100644
--- a/cmake/QtConfig.cmake.in
+++ b/cmake/QtConfig.cmake.in
@@ -44,6 +44,9 @@ list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/kwin")
if(APPLE AND (NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
# Add module directory to pick up custom Info.plist template for macOS
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos")
+elseif(APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
+ # Add module directory to pick up custom Info.plist template for iOS
+ list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/ios")
endif()
set(QT_ADDITIONAL_PACKAGES_PREFIX_PATH "" CACHE STRING "Additional directories where find(Qt6 ...) components are searched")
diff --git a/cmake/ios/MacOSXBundleInfo.plist.in b/cmake/ios/MacOSXBundleInfo.plist.in
new file mode 100644
index 0000000000..6f322398cd
--- /dev/null
+++ b/cmake/ios/MacOSXBundleInfo.plist.in
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
+
+ <key>CFBundleGetInfoString</key>
+ <string>${MACOSX_BUNDLE_INFO_STRING}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 99738c4000..53d115a6da 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -562,6 +562,144 @@ function(qt6_finalize_executable target)
if(EMSCRIPTEN)
qt_wasm_add_target_helpers("${target}")
endif()
+ if(IOS)
+ qt6_finalize_ios_app("${target}")
+ endif()
+endfunction()
+
+function(_qt_internal_find_ios_development_team_id out_var)
+ get_property(team_id GLOBAL PROPERTY _qt_internal_ios_development_team_id)
+ get_property(team_id_computed GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed)
+ if(team_id_computed)
+ # Just in case if the value is non-empty but still booly FALSE.
+ if(NOT team_id)
+ set(team_id "")
+ endif()
+ set("${out_var}" "${team_id}" PARENT_SCOPE)
+ return()
+ endif()
+
+ set_property(GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed "TRUE")
+
+ set(home_dir "$ENV{HOME}")
+ set(xcode_preferences_path "${home_dir}/Library/Preferences/com.apple.dt.Xcode.plist")
+
+ # Extract the first account name (email) from the user's Xcode preferences
+ message(DEBUG "Trying to extract an Xcode development team id from '${xcode_preferences_path}'")
+ execute_process(COMMAND "/usr/libexec/PlistBuddy"
+ -x -c "print IDEProvisioningTeams" "${xcode_preferences_path}"
+ OUTPUT_VARIABLE teams_xml
+ ERROR_VARIABLE plist_error)
+ if(teams_xml AND NOT plist_error)
+ string(REPLACE "\n" ";" teams_xml_lines "${teams_xml}")
+ foreach(xml_line ${teams_xml_lines})
+ if(xml_line MATCHES "<key>(.+)</key>")
+ set(first_account "${CMAKE_MATCH_1}")
+ string(STRIP "${first_account}" first_account)
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ if(NOT first_account)
+ message(DEBUG "Failed to extract an Xcode development team id.")
+ return()
+ endif()
+
+ # Extract the first team ID
+ execute_process(COMMAND "/usr/libexec/PlistBuddy"
+ -c "print IDEProvisioningTeams:${first_account}:0:teamID"
+ "${xcode_preferences_path}"
+ OUTPUT_VARIABLE team_id
+ ERROR_VARIABLE team_id_error)
+ if(team_id AND NOT team_id_error)
+ message(DEBUG "Successfully extracted the first encountered Xcode development team id.")
+ string(STRIP "${team_id}" team_id)
+ set_property(GLOBAL PROPERTY _qt_internal_ios_development_team_id "${team_id}")
+ set("${out_var}" "${team_id}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_qt_internal_get_ios_bundle_identifier_prefix out_var)
+ get_property(prefix GLOBAL PROPERTY _qt_internal_ios_bundle_identifier_prefix)
+ get_property(prefix_computed GLOBAL PROPERTY
+ _qt_internal_ios_bundle_identifier_prefix_computed)
+ if(prefix_computed)
+ # Just in case if the value is non-empty but still booly FALSE.
+ if(NOT prefix)
+ set(prefix "")
+ endif()
+ set("${out_var}" "${prefix}" PARENT_SCOPE)
+ return()
+ endif()
+
+ set_property(GLOBAL PROPERTY _qt_internal_ios_bundle_identifier_prefix_computed "TRUE")
+
+ set(home_dir "$ENV{HOME}")
+ set(xcode_preferences_path "${home_dir}/Library/Preferences/com.apple.dt.Xcode.plist")
+
+ message(DEBUG "Trying to extract the default bundle identifier prefix from Xcode preferences.")
+ execute_process(COMMAND "/usr/libexec/PlistBuddy"
+ -c "print IDETemplateOptions:bundleIdentifierPrefix"
+ "${xcode_preferences_path}"
+ OUTPUT_VARIABLE prefix
+ ERROR_VARIABLE prefix_error)
+ if(prefix AND NOT prefix_error)
+ message(DEBUG "Successfully extracted the default bundle indentifier prefix.")
+ string(STRIP "${prefix}" prefix)
+ else()
+ message(DEBUG "Failed to extract the default bundle indentifier prefix.")
+ endif()
+
+ if(prefix)
+ set_property(GLOBAL PROPERTY _qt_internal_ios_bundle_identifier_prefix "${prefix}")
+ set("${out_var}" "${prefix}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_qt_internal_get_default_ios_bundle_identifier out_var)
+ _qt_internal_get_ios_bundle_identifier_prefix(prefix)
+ if(NOT prefix)
+ set(prefix "com.yourcompany")
+ endif()
+ set("${out_var}" "${prefix}.\${PRODUCT_NAME:rfc1034identifier}" PARENT_SCOPE)
+endfunction()
+
+
+function(qt6_finalize_ios_app target)
+ # If user hasn't provided a development team id, try to find the first one specified
+ # in the Xcode preferences.
+ if(NOT CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM AND NOT QT_NO_SET_XCODE_DEVELOPMENT_TEAM_ID)
+ get_target_property(existing_team_id "${target}" XCODE_ATTRIBUTE_DEVELOPMENT_TEAM)
+ if(NOT existing_team_id)
+ _qt_internal_find_ios_development_team_id(team_id)
+ set_target_properties("${target}"
+ PROPERTIES XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${team_id}")
+ endif()
+ endif()
+
+ # If user hasn't provided a bundle identifier for the app, get a default identifier
+ # using the default bundle prefix from Xcode preferences and add it to the generated
+ # Info.plist file.
+ if(NOT MACOSX_BUNDLE_GUI_IDENTIFIER AND NOT QT_NO_SET_XCODE_BUNDLE_IDENTIFIER)
+ get_target_property(existing_id "${target}" MACOSX_BUNDLE_GUI_IDENTIFIER)
+ if(NOT existing_id)
+ _qt_internal_get_default_ios_bundle_identifier(bundle_id)
+ set_target_properties("${target}"
+ PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "${bundle_id}")
+ endif()
+ endif()
+
+ # Reuse the same bundle identifier for the Xcode property.
+ if(NOT CMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER
+ AND NOT QT_NO_SET_XCODE_BUNDLE_IDENTIFIER)
+ get_target_property(existing_id "${target}" XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER)
+ if(NOT existing_id)
+ set_target_properties("${target}"
+ PROPERTIES XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER
+ "${bundle_id}")
+ endif()
+ endif()
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)