iOS: Refactor default_post logic into more appropriate units

The logic was lumped together in one big file. Now that things are more
stable and the logic has proven to work over time we can split it out
into the more appropriate sub-prfs.

Change-Id: I9a40ad72ad9d7550b609e7f50fade1049dfa3ac1
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
Tor Arne Vestbø 2015-06-15 17:56:23 +02:00
parent 44520dfff6
commit 5d511039f7
5 changed files with 189 additions and 169 deletions

View File

@ -1,179 +1,24 @@
load(sdk)
# Resolve config so we don't need to use CONFIG() later on
CONFIG(iphonesimulator, iphonesimulator|iphoneos) {
CONFIG -= iphoneos
} else {
CONFIG -= iphonesimulator
CONFIG += iphoneos
}
equals(TEMPLATE, app) {
equals(TEMPLATE, app):contains(CONFIG, 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.
qt: CONFIG *= app_bundle
CONFIG *= app_bundle
app_bundle {
macx-xcode {
# There is no way to genereate Xcode projects that are limited to either
# simulator or device builds, so iphonesimulator_and_iphoneos is always
# effectivly active, even if the user disabled it explicitly.
# The Xcode generator doesn't support multiple BUILDS though (exclusive
# builds), so we have to manually set up the simulator suffix.
library_suffix_iphonesimulator.name = "$${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING}[sdk=iphonesimulator*]"
library_suffix_iphonesimulator.value = "_iphonesimulator$($${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING})"
QMAKE_MAC_XCODE_SETTINGS += library_suffix_iphonesimulator
CONFIG *= xcode_dynamic_library_suffix
} else {
# 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 create a wrapper
# makefile that takes care of generating the Xcode project, and allows
# building by calling out to xcodebuild.
TEMPLATE = aux
SOURCES =
OBJECTIVE_SOURCES =
RESOURCES =
INSTALLS =
QMAKE_EXTRA_COMPILERS =
!build_pass {
CONFIG += debug_and_release
load(resolve_config)
CONFIG += iphonesimulator_and_iphoneos
iphonesimulator.name = Simulator
iphoneos.name = Device
addExclusiveBuilds(iphonesimulator, iphoneos)
load(exclusive_builds_post)
xcode_distclean.commands = "$(DEL_FILE) -R $${TARGET}.xcodeproj"
xcode_distclean.depends = \
debug-iphonesimulator-distclean debug-iphoneos-distclean \
release-iphonesimulator-distclean release-iphoneos-distclean
QMAKE_EXTRA_TARGETS += xcode_distclean
DISTCLEAN_DEPS += xcode_distclean
mkpath($$OUT_PWD)|error("Aborting.")
args =
for(arg, QMAKE_ARGS): \
args += $$system_quote($$arg)
system("cd $$system_quote($$OUT_PWD) && $$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode")
# We have a target, even though our template is aux
CONFIG += have_target
} else {
load(resolve_config)
iphonesimulator: \
sdk = iphonesimulator
else: \
sdk = iphoneos
debug: \
cfg = debug
else: \
cfg = release
for(action, $$list(build install clean test)) {
equals(action, build) {
action_target_suffix =
action_target = all
} else: equals(action, test) {
action_target_suffix = -check
action_target = check
} else {
action_target_suffix = -$$action
action_target = $$action
}
target = $${sdk}-$${cfg}$${action_target_suffix}
xcodebuild = "xcodebuild $$action -scheme $(TARGET) -sdk $$sdk -configuration $$title($$cfg)"
equals(action, test):equals(sdk, iphoneos) {
AVAILABLE_DEVICE_IDS = "$(shell system_profiler SPUSBDataType | sed -n -E -e '/(iPhone|iPad|iPod)/,/Serial/s/ *Serial Number: *(.+)/\1/p')"
CUSTOM_DEVICE_IDS = "$(filter $(EXPORT_AVAILABLE_DEVICE_IDS), $(IOS_TEST_DEVICE_IDS))"
TEST_DEVICE_IDS = "$(strip $(if $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_AVAILABLE_DEVICE_IDS)))"
QMAKE_EXTRA_VARIABLES += AVAILABLE_DEVICE_IDS CUSTOM_DEVICE_IDS TEST_DEVICE_IDS
xcodebuild = "@$(if $(EXPORT_TEST_DEVICE_IDS),"\
"echo Running tests on $(words $(EXPORT_TEST_DEVICE_IDS)) device\\(s\\): && ("\
"$(foreach deviceid, $(EXPORT_TEST_DEVICE_IDS),"\
"(echo Testing on device ID '$(deviceid)' ... && $${xcodebuild} -destination 'platform=iOS,id=$(deviceid)' && echo) &&"\
") echo Tests completed successfully on all devices"\
"), $(error No iOS devices connected, please connect at least one device that can be used for testing.))"
}
$${target}.commands = $$xcodebuild
QMAKE_EXTRA_TARGETS += $$target
$${action_target}.depends += $$target
QMAKE_EXTRA_TARGETS *= $${action_target}
}
xcode_build_dir_distclean.commands = "$(DEL_FILE) -R $$title($$cfg)-$${sdk}"
xcode_build_dir_distclean.depends = clean
QMAKE_EXTRA_TARGETS += xcode_build_dir_distclean
distclean.depends = xcode_build_dir_distclean
QMAKE_EXTRA_TARGETS += distclean
}
}
}
} else: equals(TEMPLATE, lib) {
iphonesimulator.name = Simulator
iphoneos.name = Device
addExclusiveBuilds(iphonesimulator, iphoneos)
} else: equals(TEMPLATE, subdirs) {
# Prevent recursion into host_builds
for(subdir, SUBDIRS) {
contains($${subdir}.CONFIG, host_build) {
$${subdir}.CONFIG += no_iphoneos_target no_iphonesimulator_target
# Other targets which we do want to recurse into may depend on this target,
# for example corelib depends on moc, rcc, bootstrap, etc, and other libs
# may depend on host-tools that are needed to build the lib, so we resolve
# the final target name and redirect it to the base target, so that the
# dependency chain is not broken for the other targets.
!isEmpty($${subdir}.target) {
target = $$eval($${subdir}.target)
} else {
!isEmpty($${subdir}.file): \
file = $$eval($${subdir}.file)
else: !isEmpty($${subdir}.subdir): \
file = $$eval($${subdir}.subdir)
else: \
file = $$subdir
target = sub-$$file
}
target ~= s,[^a-zA-Z0-9_],-,
$${target}-iphonesimulator.depends = $$target
$${target}-iphoneos.depends = $$target
QMAKE_EXTRA_TARGETS += $${target}-iphonesimulator $${target}-iphoneos
}
}
prepareRecursiveTarget(iphonesimulator)
prepareRecursiveTarget(iphoneos)
QMAKE_EXTRA_TARGETS += iphonesimulator iphoneos
} else: equals(TEMPLATE, aux) {
# Dummy targets for the 'aux' TEMPLATE, so we can always recurse
QMAKE_EXTRA_TARGETS *= iphonesimulator iphoneos
# 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_device_family.name = TARGETED_DEVICE_FAMILY
ios_device_family.value = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY
@ -251,5 +96,3 @@ macx-xcode {
QMAKE_OBJECTIVE_CFLAGS += $$arch_flags
QMAKE_LFLAGS += $$arch_flags
}
load(default_post)

View File

@ -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)

View File

@ -0,0 +1,64 @@
xcodebuild {
# Xcode project files always support both Debug and Release configurations
# and iOS device and simulator targets, so we make sure the wrapper-makefile
# also does.
CONFIG += debug_and_release iphonesimulator_and_iphoneos
}
load(resolve_config)
CONFIG(iphonesimulator, iphonesimulator|iphoneos): \
CONFIG -= iphoneos
else: \
CONFIG -= iphonesimulator
macx-xcode {
# There is no way to genereate Xcode projects that are limited to either
# simulator or device builds, so iphonesimulator_and_iphoneos is always
# effectivly active, even if the user disabled it explicitly.
# The Xcode generator doesn't support multiple BUILDS though (exclusive
# builds), so we have to manually set up the simulator suffix.
library_suffix_iphonesimulator.name = "$${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING}[sdk=iphonesimulator*]"
library_suffix_iphonesimulator.value = "_iphonesimulator$($${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING})"
QMAKE_MAC_XCODE_SETTINGS += library_suffix_iphonesimulator
CONFIG *= xcode_dynamic_library_suffix
} else {
iphonesimulator.name = Simulator
iphoneos.name = Device
addExclusiveBuilds(iphonesimulator, iphoneos)
}
equals(TEMPLATE, subdirs) {
# Prevent recursion into host_builds
for(subdir, SUBDIRS) {
contains($${subdir}.CONFIG, host_build) {
$${subdir}.CONFIG += no_iphoneos_target no_iphonesimulator_target
# Other targets which we do want to recurse into may depend on this target,
# for example corelib depends on moc, rcc, bootstrap, etc, and other libs
# may depend on host-tools that are needed to build the lib, so we resolve
# the final target name and redirect it to the base target, so that the
# dependency chain is not broken for the other targets.
!isEmpty($${subdir}.target) {
target = $$eval($${subdir}.target)
} else {
!isEmpty($${subdir}.file): \
file = $$eval($${subdir}.file)
else: !isEmpty($${subdir}.subdir): \
file = $$eval($${subdir}.subdir)
else: \
file = $$subdir
target = sub-$$file
}
target ~= s,[^a-zA-Z0-9_],-,
$${target}-iphonesimulator.depends = $$target
$${target}-iphoneos.depends = $$target
QMAKE_EXTRA_TARGETS += $${target}-iphonesimulator $${target}-iphoneos
}
}
}

View File

@ -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
}

View File

@ -0,0 +1,93 @@
# 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 =
!build_pass {
# Top level makefile that aggregates all exclusive builds
!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")
distclean_files += $${TARGET}.xcodeproj
# Pretend we have a target, even though our template is aux
CONFIG += have_target
} else {
# Leaf makefile for a single exclusive build
iphonesimulator: \
sdk = iphonesimulator
else: \
sdk = iphoneos
debug: \
cfg = debug
else: \
cfg = release
for(action, $$list(build install clean test)) {
equals(action, build) {
action_target_suffix =
action_target = all
} else: equals(action, test) {
action_target_suffix = -check
action_target = check
} else {
action_target_suffix = -$$action
action_target = $$action
}
target = $${sdk}-$${cfg}$${action_target_suffix}
xcodebuild = "xcodebuild $$action -scheme $(TARGET) -sdk $$sdk -configuration $$title($$cfg)"
equals(action, test):equals(sdk, iphoneos) {
AVAILABLE_DEVICE_IDS = "$(shell system_profiler SPUSBDataType | sed -n -E -e '/(iPhone|iPad|iPod)/,/Serial/s/ *Serial Number: *(.+)/\1/p')"
CUSTOM_DEVICE_IDS = "$(filter $(EXPORT_AVAILABLE_DEVICE_IDS), $(IOS_TEST_DEVICE_IDS))"
TEST_DEVICE_IDS = "$(strip $(if $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_AVAILABLE_DEVICE_IDS)))"
QMAKE_EXTRA_VARIABLES += AVAILABLE_DEVICE_IDS CUSTOM_DEVICE_IDS TEST_DEVICE_IDS
xcodebuild = "@$(if $(EXPORT_TEST_DEVICE_IDS),"\
"echo Running tests on $(words $(EXPORT_TEST_DEVICE_IDS)) device\\(s\\): && ("\
"$(foreach deviceid, $(EXPORT_TEST_DEVICE_IDS),"\
"(echo Testing on device ID '$(deviceid)' ... && $${xcodebuild} -destination 'platform=iOS,id=$(deviceid)' && echo) &&"\
") echo Tests completed successfully on all devices"\
"), $(error No iOS devices connected, please connect at least one device that can be used for testing.))"
}
$${target}.commands = $$xcodebuild
QMAKE_EXTRA_TARGETS += $$target
$${action_target}.depends += $$target
QMAKE_EXTRA_TARGETS *= $${action_target}
}
# Remove build dir
distclean_files += $$title($$cfg)-$${sdk}
}
distclean_xcodebuild.commands = -$(DEL_FILE) -R $$distclean_files
distclean.depends += distclean_xcodebuild
QMAKE_EXTRA_TARGETS += distclean distclean_xcodebuild