diff options
Diffstat (limited to 'mkspecs/features/uikit')
-rw-r--r-- | mkspecs/features/uikit/bitcode.prf | 15 | ||||
-rw-r--r-- | mkspecs/features/uikit/default_post.prf | 104 | ||||
-rw-r--r-- | mkspecs/features/uikit/default_pre.prf | 22 | ||||
-rwxr-xr-x | mkspecs/features/uikit/device_destinations.sh | 72 | ||||
-rwxr-xr-x | mkspecs/features/uikit/devices.pl | 50 | ||||
-rw-r--r-- | mkspecs/features/uikit/exclusive_builds_post.prf | 8 | ||||
-rw-r--r-- | mkspecs/features/uikit/qt.prf | 33 | ||||
-rw-r--r-- | mkspecs/features/uikit/qt_config.prf | 19 | ||||
-rw-r--r-- | mkspecs/features/uikit/qt_parts.prf | 5 | ||||
-rw-r--r-- | mkspecs/features/uikit/resolve_config.prf | 11 | ||||
-rw-r--r-- | mkspecs/features/uikit/sdk.prf | 29 | ||||
-rw-r--r-- | mkspecs/features/uikit/testcase.prf | 12 | ||||
-rw-r--r-- | mkspecs/features/uikit/testcase_targets.prf | 3 | ||||
-rw-r--r-- | mkspecs/features/uikit/xcodebuild.mk | 102 | ||||
-rw-r--r-- | mkspecs/features/uikit/xcodebuild.prf | 65 |
15 files changed, 550 insertions, 0 deletions
diff --git a/mkspecs/features/uikit/bitcode.prf b/mkspecs/features/uikit/bitcode.prf new file mode 100644 index 0000000000..a1dff19eb3 --- /dev/null +++ b/mkspecs/features/uikit/bitcode.prf @@ -0,0 +1,15 @@ +lessThan(QMAKE_XCODE_VERSION, "7.0") { + warning("You need to update Xcode to version 7 or newer to support bitcode") +} else { + release:device { + QMAKE_CFLAGS += -fembed-bitcode + QMAKE_CXXFLAGS += -fembed-bitcode + QMAKE_OBJECTIVE_CFLAGS += -fembed-bitcode + QMAKE_LFLAGS += -fembed-bitcode + } else { + QMAKE_CFLAGS += -fembed-bitcode-marker + QMAKE_CXXFLAGS += -fembed-bitcode-marker + QMAKE_OBJECTIVE_CFLAGS += -fembed-bitcode-marker + QMAKE_LFLAGS += -fembed-bitcode-marker + } +} diff --git a/mkspecs/features/uikit/default_post.prf b/mkspecs/features/uikit/default_post.prf new file mode 100644 index 0000000000..9a231ffc84 --- /dev/null +++ b/mkspecs/features/uikit/default_post.prf @@ -0,0 +1,104 @@ +equals(TEMPLATE, app):qt { + # If the application uses Qt, it needs to be an application bundle + # to be able to deploy and run on iOS. The only exception to this + # is if you're working with a jailbroken device and can run the + # resulting binary from the console/over SSH, but that's not a + # use-case we care about, so no need to complicate the logic. + CONFIG *= app_bundle + + # For Qt applications we want Xcode project files as the generated output, + # but since qmake doesn't handle the transition between makefiles and Xcode + # project files (which happens when using subdirs), we can't just override + # MAKEFILE_GENERATOR. Instead, we generate the Xcode project by spawning a + # child qmake process with -spec macx-xcode and let the top level qmake + # process generate a wrapper makefile that forwards everything to xcodebuild. + equals(MAKEFILE_GENERATOR, UNIX): \ + CONFIG = xcodebuild $$CONFIG +} + +load(default_post) + +macx-xcode { + ios:isEmpty(QMAKE_APPLE_TARGETED_DEVICE_FAMILY):!isEmpty(QMAKE_IOS_TARGETED_DEVICE_FAMILY) { + warning("QMAKE_IOS_TARGETED_DEVICE_FAMILY is deprecated; use QMAKE_APPLE_TARGETED_DEVICE_FAMILY") + QMAKE_APPLE_TARGETED_DEVICE_FAMILY = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY + } + + device_family.name = TARGETED_DEVICE_FAMILY + device_family.value = $$QMAKE_APPLE_TARGETED_DEVICE_FAMILY + QMAKE_MAC_XCODE_SETTINGS += device_family + + ios { + # If QMAKE_BUNDLE_DATA contains an asset catalog that includes an + # AppIcon.appiconset, we configure Xcode to use it for app icons. + for(bundle_data, QMAKE_BUNDLE_DATA) { + for(bundle_file, $${bundle_data}.files) { + !contains(bundle_file, .*\.xcassets$): next() + !exists($$absolute_path($$bundle_file/AppIcon.appiconset, $$_PRO_FILE_PWD_)): next() + + asset_catalog_appicon.name = "ASSETCATALOG_COMPILER_APPICON_NAME" + asset_catalog_appicon.value = "AppIcon" + QMAKE_MAC_XCODE_SETTINGS += asset_catalog_appicon + break() + } + !isEmpty(asset_catalog_appicon.name): break() + } + + # Set up default 4-inch iPhone/iPod launch image so that our apps + # support the full screen resolution of those devices. + qmake_launch_image = Default-568h@2x.png + qmake_copy_image.input = $$QMAKESPEC/$$qmake_launch_image + qmake_copy_image.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$qmake_launch_image + qmake_copy_image.CONFIG = verbatim + QMAKE_SUBSTITUTES += qmake_copy_image + qmake_launch_images.files = $$qmake_copy_image.output + QMAKE_BUNDLE_DATA += qmake_launch_images + + lessThan(QMAKE_XCODE_VERSION, "6.0") { + warning("You need to update Xcode to version 6 or newer to fully support iPhone6/6+") + } else { + # Set up default LaunchScreen to support iPhone6/6+ + qmake_launch_screen = LaunchScreen.xib + qmake_copy_launch_screen.input = $$QMAKESPEC/$$qmake_launch_screen + qmake_copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$qmake_launch_screen + QMAKE_SUBSTITUTES += qmake_copy_launch_screen + qmake_launch_screens.files = $$qmake_copy_launch_screen.output + QMAKE_BUNDLE_DATA += qmake_launch_screens + } + } +} + +macx-xcode { + arch_device.name = "ARCHS[sdk=$${device.sdk}*]" + arch_simulator.name = "ARCHS[sdk=$${simulator.sdk}*]" + + arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS + arch_simulator.value = $$QMAKE_APPLE_SIMULATOR_ARCHS + QMAKE_XCODE_ARCHS = $$QMAKE_APPLE_DEVICE_ARCHS $$QMAKE_APPLE_SIMULATOR_ARCHS + + QMAKE_MAC_XCODE_SETTINGS += arch_device arch_simulator + + only_active_arch.name = ONLY_ACTIVE_ARCH + only_active_arch.value = YES + only_active_arch.build = debug + QMAKE_MAC_XCODE_SETTINGS += only_active_arch +} else { + VALID_ARCHS = + !simulator|simulator_and_device: VALID_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS + simulator: VALID_ARCHS += $$QMAKE_APPLE_SIMULATOR_ARCHS + + single_arch: VALID_ARCHS = $$first(VALID_ARCHS) + + ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) + ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ACTIVE_ARCHS), $(EXPORT_ACTIVE_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch)) + + QMAKE_EXTRA_VARIABLES += VALID_ARCHS ACTIVE_ARCHS ARCH_ARGS + + arch_flags = $(EXPORT_ARCH_ARGS) + + QMAKE_CFLAGS += $$arch_flags + QMAKE_CXXFLAGS += $$arch_flags + QMAKE_LFLAGS += $$arch_flags + + QMAKE_PCH_ARCHS = $$VALID_ARCHS +} diff --git a/mkspecs/features/uikit/default_pre.prf b/mkspecs/features/uikit/default_pre.prf new file mode 100644 index 0000000000..8b5b3ccfe9 --- /dev/null +++ b/mkspecs/features/uikit/default_pre.prf @@ -0,0 +1,22 @@ + +load(default_pre) + +!isEmpty(QT_VERSION) { + qtConfig(simulator_and_device)|contains(QMAKE_MAC_SDK, ^$${device.sdk}.*): \ + CONFIG += device $${device.sdk} + qtConfig(simulator_and_device)|contains(QMAKE_MAC_SDK, ^$${simulator.sdk}.*): \ + CONFIG += simulator $${simulator.sdk} + + qtConfig(simulator_and_device) { + # For a simulator_and_device build all the config tests + # are based on the device's ARM SDK, but we know that the simulator + # is Intel and that we support SSE/SSE2. + QT_CPU_FEATURES.$$QT_ARCH += sse sse2 + CONFIG += sse sse2 + DEFINES += QT_COMPILER_SUPPORTS_SSE2 + } +} + +# Check for supported Xcode versions +lessThan(QMAKE_XCODE_VERSION, "4.3"): \ + error("This mkspec requires Xcode 4.3 or later") diff --git a/mkspecs/features/uikit/device_destinations.sh b/mkspecs/features/uikit/device_destinations.sh new file mode 100755 index 0000000000..162ad01aaf --- /dev/null +++ b/mkspecs/features/uikit/device_destinations.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +booted_simulator=$($DIR/devices.pl "$1" "Booted" "NOT unavailable" | tail -n 1) +echo "SIMULATOR_DEVICES = $booted_simulator" + +xcodebuild test -scheme $2 -destination 'id=0' -destination-timeout 1 2>&1| sed -n 's/{ \(platform:.*\) }/\1/p' | while read destination; do + id=$(echo $destination | sed -n -E 's/.*id:([^ ,]+).*/\1/p') + [[ $id == *"placeholder"* ]] && continue + + echo $destination | tr ',' '\n' | while read keyval; do + key=$(echo $keyval | cut -d ':' -f 1 | tr '[:lower:]' '[:upper:]') + val=$(echo $keyval | cut -d ':' -f 2) + echo "%_$id: DESTINATION_${key} = $val" + + if [ $key = 'PLATFORM' ]; then + if [ "$val" = "iOS" ]; then + echo "HARDWARE_DEVICES += $id" + elif [ "$val" = "iOS Simulator" -a "$id" != "$booted_simulator" ]; then + echo "SIMULATOR_DEVICES += $id" + elif [ "$val" = "tvOS" ]; then + echo "HARDWARE_DEVICES += $id" + elif [ "$val" = "tvOS Simulator" -a "$id" != "$booted_simulator" ]; then + echo "SIMULATOR_DEVICES += $id" + elif [ "$val" = "watchOS" ]; then + echo "HARDWARE_DEVICES += $id" + elif [ "$val" = "watchOS Simulator" -a "$id" != "$booted_simulator" ]; then + echo "SIMULATOR_DEVICES += $id" + fi + fi + done + echo +done diff --git a/mkspecs/features/uikit/devices.pl b/mkspecs/features/uikit/devices.pl new file mode 100755 index 0000000000..eb45d1dab9 --- /dev/null +++ b/mkspecs/features/uikit/devices.pl @@ -0,0 +1,50 @@ +#!/usr/bin/perl + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL21$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see http://www.qt.io/terms-conditions. For further +## information use the contact form at http://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 or version 3 as published by the Free +## Software Foundation and appearing in the file LICENSE.LGPLv21 and +## LICENSE.LGPLv3 included in the packaging of this file. Please review the +## following information to ensure the GNU Lesser General Public License +## requirements will be met: https://www.gnu.org/licenses/lgpl.html and +## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## As a special exception, The Qt Company gives you certain additional +## rights. These rights are described in The Qt Company LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## $QT_END_LICENSE$ +## +############################################################################# + +$output = `xcrun simctl list devices --json 2>&1`; +$output =~ s/\n//g; + +BLOCK: +foreach $block ($output =~ /{.*?}/g) { + foreach $filter (@ARGV) { + if ($filter =~ /^NOT\s(.*)/) { + $block =~ /$1/ && next BLOCK; + } else { + $block =~ /$filter/ || next BLOCK; + } + } + $block =~ /udid[:|\s|\"]+(.*)\"/; + print "$1\n"; +} diff --git a/mkspecs/features/uikit/exclusive_builds_post.prf b/mkspecs/features/uikit/exclusive_builds_post.prf new file mode 100644 index 0000000000..1fb0a55846 --- /dev/null +++ b/mkspecs/features/uikit/exclusive_builds_post.prf @@ -0,0 +1,8 @@ + +xcodebuild { + # Prevent qmake from generating empty output dirs for each exclusive build, + # as Xcode will do this by itself, and with a different name. + QMAKE_DIR_REPLACE = +} + +load(exclusive_builds_post) diff --git a/mkspecs/features/uikit/qt.prf b/mkspecs/features/uikit/qt.prf new file mode 100644 index 0000000000..4475c137dc --- /dev/null +++ b/mkspecs/features/uikit/qt.prf @@ -0,0 +1,33 @@ + +qt_depends = $$resolve_depends(QT, "QT.") +!watchos:equals(TEMPLATE, app):contains(qt_depends, gui(-private)?) { + LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms + + lib_name = qios + lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() + LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) + + !bitcode { + # By marking qt_registerPlatformPlugin as undefined, we ensure that + # the plugin.o translation unit is considered for inclusion in + # the final binary, which in turn ensures that the plugin's + # static initializer is included and run. + QMAKE_LFLAGS += -u _qt_registerPlatformPlugin + + # We do link and dependency resolution for the platform plugin + # manually, since we know we always need the plugin, so we don't + # need to generate an import for it. + QTPLUGIN.platforms = - + } + + !no_main_wrapper { + # The LC_MAIN load command available in iOS 6.0 and above allows dyld to + # directly call the entrypoint instead of going through _start in crt.o. + # Passing -e to the linker changes the entrypoint from _main to our custom + # wrapper that calls UIApplicationMain and dispatches back to main() once + # the application has started up and is ready to initialize QApplication. + QMAKE_LFLAGS += -Wl,-e,_qt_main_wrapper + } +} + +load(qt) diff --git a/mkspecs/features/uikit/qt_config.prf b/mkspecs/features/uikit/qt_config.prf new file mode 100644 index 0000000000..5fa5a536f8 --- /dev/null +++ b/mkspecs/features/uikit/qt_config.prf @@ -0,0 +1,19 @@ +load(qt_config) + +isEmpty(QT_ARCH) { + # The configure tests are run without QT_ARCH being resolved yet, which + # means we fail to pass -arch to the compiler, resulting in broke tests. + # As the Xcode toolchain doesn't seem to have a way to auto-detect the + # arch based on the SDK, we have to hard-code the arch for configure. + contains(QMAKE_MAC_SDK, $${device.sdk}.*) { + QT_ARCH = arm + } else { # Simulator + ios: QT_ARCH = i386 + tvos: QT_ARCH = x64 + watchos: QT_ARCH = i386 + } + + # Prevent the arch/config tests from building as multi-arch binaries, + # as we only want the lowest common denominator features. + CONFIG += single_arch +} diff --git a/mkspecs/features/uikit/qt_parts.prf b/mkspecs/features/uikit/qt_parts.prf new file mode 100644 index 0000000000..81814a62b0 --- /dev/null +++ b/mkspecs/features/uikit/qt_parts.prf @@ -0,0 +1,5 @@ + +# Disable tests for anything but qtbase for now +!equals(TARGET, qtbase): QT_BUILD_PARTS -= tests + +load(qt_parts) diff --git a/mkspecs/features/uikit/resolve_config.prf b/mkspecs/features/uikit/resolve_config.prf new file mode 100644 index 0000000000..70ddd8be52 --- /dev/null +++ b/mkspecs/features/uikit/resolve_config.prf @@ -0,0 +1,11 @@ + +xcodebuild { + # Xcode project files always support both Debug and Release configurations + # and device and simulator targets, so we make sure the wrapper-makefile + # also does. + CONFIG += debug_and_release simulator_and_device +} + +load(resolve_config) + +!macx-xcode:xcodebuild: addExclusiveBuilds(simulator, device) diff --git a/mkspecs/features/uikit/sdk.prf b/mkspecs/features/uikit/sdk.prf new file mode 100644 index 0000000000..54674eb396 --- /dev/null +++ b/mkspecs/features/uikit/sdk.prf @@ -0,0 +1,29 @@ + +# In case the user sets the SDK manually +contains(QMAKE_MAC_SDK, ^$${simulator.sdk}.*) { + !isEmpty(QT_VERSION):qtConfig(simulator_and_device): \ + error("Simulator is handled automatically for simulator_and_device") + + CONFIG += simulator $${simulator.sdk} +} + +build_pass:simulator: \ + QMAKE_MAC_SDK ~= s,^$${device.sdk},$${simulator.sdk}, + +load(sdk) + +macx-xcode { + sdk_path_device.name = "QMAKE_MAC_SDK_PATH[sdk=$${device.sdk}*]" + sdk_path_device.value = $$xcodeSDKInfo(Path, $${device.sdk}) + sdk_path_simulator.name = "QMAKE_MAC_SDK_PATH[sdk=$${simulator.sdk}*]" + sdk_path_simulator.value = $$xcodeSDKInfo(Path, $${simulator.sdk}) + QMAKE_MAC_XCODE_SETTINGS += sdk_path_device sdk_path_simulator + QMAKE_MAC_SDK_PATH = "$(QMAKE_MAC_SDK_PATH)" + + sdk_platform_path_device.name = "QMAKE_MAC_SDK_PLATFORM_PATH[sdk=$${device.sdk}*]" + sdk_platform_path_device.value = $$xcodeSDKInfo(PlatformPath, $${device.sdk}) + sdk_platform_path_simulator.name = "QMAKE_MAC_SDK_PLATFORM_PATH[sdk=$${simulator.sdk}*]" + sdk_platform_path_simulator.value = $$xcodeSDKInfo(PlatformPath, $${simulator.sdk}) + QMAKE_MAC_XCODE_SETTINGS += sdk_platform_path_device sdk_platform_path_simulator + QMAKE_MAC_SDK_PLATFORM_PATH = "$(QMAKE_MAC_SDK_PLATFORM_PATH)" +} diff --git a/mkspecs/features/uikit/testcase.prf b/mkspecs/features/uikit/testcase.prf new file mode 100644 index 0000000000..e16c163ffa --- /dev/null +++ b/mkspecs/features/uikit/testcase.prf @@ -0,0 +1,12 @@ +# Pretend we have a target, even though our template is aux +xcodebuild: \ + CONFIG += have_target + +load(testcase) + +# We provide our own check logic +xcodebuild { + check.depends = + check.commands = + QMAKE_EXTRA_TARGETS *= check +} diff --git a/mkspecs/features/uikit/testcase_targets.prf b/mkspecs/features/uikit/testcase_targets.prf new file mode 100644 index 0000000000..e0a2922c3f --- /dev/null +++ b/mkspecs/features/uikit/testcase_targets.prf @@ -0,0 +1,3 @@ +# For the xcodebuild wrapper makefile we deal with test targets manually +!xcodebuild: \ + load(testcase_targets) diff --git a/mkspecs/features/uikit/xcodebuild.mk b/mkspecs/features/uikit/xcodebuild.mk new file mode 100644 index 0000000000..57011eaf01 --- /dev/null +++ b/mkspecs/features/uikit/xcodebuild.mk @@ -0,0 +1,102 @@ + +# We don't want xcodebuild to run in parallel +.NOTPARALLEL: + +# Functions +targets = $(foreach target, $(EXPORT_SUBTARGETS), $(target)-$(strip $(1))) +toupper = $(shell echo $1 | tr '[:lower:]' '[:upper:]') +tolower = $(shell echo $1 | tr '[:upper:]' '[:lower:]') +basesdk = $(shell echo $1 | sed 's/[0-9.]*$$//') + +# Explicit comma variable +, := , + +# Default targets +first: build +all: build_all + +.DEFAULT_GOAL = first + +# Top level targets +build: build_first +clean: clean_first +install: install_first +check: check_first +distclean: clean_all + +$(EXPORT_SUBTARGETS): % : %-build + +# Generic targets +%_first: $(firstword $(call targets, %)) ; +%_all: $(call targets, %) ; + +# Actions +%-build: ACTION = build +%-build: xcodebuild-% ; + +%-clean: ACTION = clean +%-clean: xcodebuild-% ; + +%-install: ACTION = install +%-install: xcodebuild-% ; + +# Simulator doesn't support archiving +%-simulator-install: ACTION = build +simulator-install: ACTION = build + +# Limit check to a single configuration +%-device-check: check-device ; +%-simulator-check: check-simulator ; + +# SDK +%-device: SDK = $(DEVICE_SDK) +%-simulator: SDK = $(SIMULATOR_SDK) + +# Configuration +release-%: CONFIGURATION = Release +debug-%: CONFIGURATION = Debug + +MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST))) + +# Test and build (device) destinations +ifneq ($(filter check%,$(MAKECMDGOALS)),) + ifeq ($(DEVICES),) + $(info Enumerating test destinations (you may override this by setting DEVICES explicitly), please wait...) + DESTINATIONS_INCLUDE = /tmp/device_destinations.mk + $(shell $(MAKEFILE_DIR)device_destinations.sh '$(EXPORT_DEVICE_FILTER)' $(TARGET) > $(DESTINATIONS_INCLUDE)) + include $(DESTINATIONS_INCLUDE) + endif +endif + +%-simulator: DEVICES = $(firstword $(SIMULATOR_DEVICES)) +%-device: DEVICES = $(HARDWARE_DEVICES) + +GENERIC_DEVICE_DESTINATION := $(EXPORT_GENERIC_DEVICE_DESTINATION) +GENERIC_SIMULATOR_DESTINATION := "id=$(shell $(MAKEFILE_DIR)devices.pl '$(EXPORT_DEVICE_FILTER)' "NOT unavailable" | tail -n 1)" + +%-simulator: DESTINATION = $(if $(DESTINATION_ID),"id=$(DESTINATION_ID)",$(GENERIC_SIMULATOR_DESTINATION)) +%-device: DESTINATION = $(if $(DESTINATION_ID),"id=$(DESTINATION_ID)",$(GENERIC_DEVICE_DESTINATION)) + +# Xcodebuild + +DESTINATION_MESSAGE = "Running $(call tolower,$(CONFIGURATION)) $(ACTION) \ + on '$(DESTINATION_NAME)' ($(DESTINATION_ID))$(if $(DESTINATION_OS),$(,) $(DESTINATION_PLATFORM) $(DESTINATION_OS),)" + +xcodebuild-%: + @$(if $(DESTINATION_NAME), echo $(DESTINATION_MESSAGE),) + xcodebuild $(ACTION) -project $(TARGET).xcodeproj -scheme $(TARGET) $(if $(SDK), -sdk $(SDK),) $(if $(CONFIGURATION), -configuration $(CONFIGURATION),) $(if $(DESTINATION), -destination $(DESTINATION) -destination-timeout 1,) $(if $(INSTALL_ROOT), DSTROOT=$(INSTALL_ROOT),) + +xcodebuild-check-device_%: DESTINATION_ID=$(lastword $(subst _, ,$@)) + +# Special check target (requires SECONDEXPANSION due to devices) +.SECONDEXPANSION: +check-%: ACTION = test +check-%: $$(foreach device, $$(DEVICES), xcodebuild-check-device_$$(device)) ; + @echo $(if $^, Ran $(call tolower,$(CONFIGURATION)) tests on $(words $^) $(SDK) destination\(s\): $(DEVICES), No compatible test devices found for \'$(SDK)\' SDK && false) + +# Determined by device +check-%: SDK = + +# Default to debug for testing +check-%: CONFIGURATION = Debug + diff --git a/mkspecs/features/uikit/xcodebuild.prf b/mkspecs/features/uikit/xcodebuild.prf new file mode 100644 index 0000000000..82bcd9a315 --- /dev/null +++ b/mkspecs/features/uikit/xcodebuild.prf @@ -0,0 +1,65 @@ + +# For Qt applications we want Xcode project files as the generated output, +# but since qmake doesn't handle the transition between makefiles and Xcode +# project files (which happens when using subdirs), we can't just override +# MAKEFILE_GENERATOR. Instead, we generate the Xcode project by spawing a +# child qmake process with -spec macx-xcode and let the top level qmake +# process generate a wrapper makefile that forwards everything to xcodebuild. + +TEMPLATE = aux + +SOURCES = +OBJECTIVE_SOURCES = +RESOURCES = +INSTALLS = +QMAKE_EXTRA_COMPILERS = + +!mkpath($$OUT_PWD): \ + error("Failed to create $$OUT_PWD") + +args = +for(arg, QMAKE_ARGS): \ + args += $$system_quote($$arg) + +cmd = "$$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode" +debug(1, "Generating Xcode project in $$OUT_PWD using '$$cmd'") +system("cd $$system_quote($$OUT_PWD) && $$cmd") + +# Subtargets + +for(build, BUILDS): \ + SUBTARGETS += $$eval($${build}.target) +QMAKE_EXTRA_VARIABLES += SUBTARGETS + +CONFIG += no_default_goal_deps + +DEVICE_SDK = $${device.sdk} +SIMULATOR_SDK = $${simulator.sdk} +ios { + DEVICE_FILTER = "iPhone|iPad" + GENERIC_DEVICE_DESTINATION = "generic/platform=iOS" +} +tvos { + DEVICE_FILTER = "Apple TV" + GENERIC_DEVICE_DESTINATION = "generic/platform=tvOS" +} +watchos { + DEVICE_FILTER = "Apple Watch" + GENERIC_DEVICE_DESTINATION = "generic/platform=watchOS" +} +QMAKE_EXTRA_VARIABLES += DEVICE_SDK SIMULATOR_SDK DEVICE_FILTER GENERIC_DEVICE_DESTINATION + +QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/xcodebuild.mk) + +# Distclean + +distfiles = $${TARGET}.xcodeproj +for(build, BUILDS): \ + distfiles += $$title($$eval($${build}.target)) +distclean_xcodebuild.commands = -$(DEL_FILE) -R $$distfiles + +distclean.depends += clean_all distclean_xcodebuild +QMAKE_EXTRA_TARGETS += distclean distclean_xcodebuild + +# Empty exclusive builds, we've set them up manually +BUILDS = |