Skip to content

Commit

Permalink
Share the multi-arch infrastructure between UIKit and macOS
Browse files Browse the repository at this point in the history
There's no reason for this to be separated, regardless of the
support status of i386 macOS builds. Additional architectures may
appear in the future (and currently there's actually 3 - i386,
x86_64, and x86_64h for Haswell CPUs). So this feature could be
used to get combined generic x86_64 and Haswell builds. Some
system libraries appear to have an x86_64h slice in Sierra.

[ChangeLog][Build System] Support for universal binaries on macOS
has been re-introduced.

Change-Id: I1c89904addf024431fdb3ad03ea8ab85da7240ad
Reviewed-by: Oswald Buddenhagen <[email protected]>
Reviewed-by: Jake Petroules <[email protected]>
  • Loading branch information
jakepetroules committed Sep 29, 2016
1 parent e66d181 commit 28f5d79
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 100 deletions.
6 changes: 6 additions & 0 deletions mkspecs/common/macx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@
QMAKE_PLATFORM += macos osx macx
QMAKE_MAC_SDK = macosx

device.sdk = macosx
device.target = device
device.dir_affix = $${device.sdk}
device.CONFIG = $${device.sdk}
device.deployment_identifier = $${device.sdk}

include(mac.conf)
59 changes: 50 additions & 9 deletions mkspecs/features/mac/default_post.prf
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
load(default_post)

# Ensure that we process sdk.prf first, as it will update QMAKE_CXX
# and friends that other features/extra compilers may depend on.
sdk: load(sdk)

!no_objective_c:CONFIG += objective_c

qt {
Expand Down Expand Up @@ -33,18 +38,54 @@ qt {

!bitcode: QMAKE_LFLAGS += $$QMAKE_LFLAGS_HEADERPAD

macx-xcode:!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
debug_information_format.name = DEBUG_INFORMATION_FORMAT
debug_information_format.value = $$QMAKE_XCODE_DEBUG_INFORMATION_FORMAT
debug_information_format.build = debug
QMAKE_MAC_XCODE_SETTINGS += debug_information_format
macx-xcode {
!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
debug_information_format.name = DEBUG_INFORMATION_FORMAT
debug_information_format.value = $$QMAKE_XCODE_DEBUG_INFORMATION_FORMAT
debug_information_format.build = debug
QMAKE_MAC_XCODE_SETTINGS += debug_information_format
}

QMAKE_XCODE_ARCHS =

arch_device.name = "ARCHS[sdk=$${device.sdk}*]"
arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_MAC_XCODE_SETTINGS += arch_device

simulator {
arch_simulator.name = "ARCHS[sdk=$${simulator.sdk}*]"
arch_simulator.value = $$QMAKE_APPLE_SIMULATOR_ARCHS
QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_SIMULATOR_ARCHS
QMAKE_MAC_XCODE_SETTINGS += 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
}

cache(QMAKE_XCODE_DEVELOPER_PATH, stash)
cache(QMAKE_XCODE_VERSION, stash)

QMAKE_XCODE_LIBRARY_SUFFIX = $$qtPlatformTargetSuffix()

# Ensure that we process sdk.prf first, as it will update QMAKE_CXX
# and friends that other features/extra compilers may depend on.
sdk: load(sdk)
73 changes: 42 additions & 31 deletions mkspecs/features/mac/sdk.prf
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,33 @@ for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_
}

!equals(MAKEFILE_GENERATOR, XCODE) {
uikit:!host_build {
ios: deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET
tvos: deployment_target = $$QMAKE_TVOS_DEPLOYMENT_TARGET
watchos: deployment_target = $$QMAKE_WATCHOS_DEPLOYMENT_TARGET

!simulator|simulator_and_device: device_archs = $$QMAKE_APPLE_DEVICE_ARCHS
simulator: simulator_archs = $$QMAKE_APPLE_SIMULATOR_ARCHS
archs = $$device_archs $$simulator_archs
macos: deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET
ios: deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET
tvos: deployment_target = $$QMAKE_TVOS_DEPLOYMENT_TARGET
watchos: deployment_target = $$QMAKE_WATCHOS_DEPLOYMENT_TARGET

!simulator|simulator_and_device: device_archs = $$QMAKE_APPLE_DEVICE_ARCHS
simulator: simulator_archs = $$QMAKE_APPLE_SIMULATOR_ARCHS
archs = $$device_archs $$simulator_archs

single_arch {
device_archs = $$first(device_archs)
simulator_archs = $$first(simulator_archs)
archs = $$first(archs)
}

# If we're doing a simulator_and_device build, device and simulator architectures
# use different paths and flags for the sysroot and deployment target switch, so we
# must multiplex them across multiple architectures using -Xarch. Otherwise we fall
# back to the simple path. This is not strictly necessary but results in cleaner
# command lines and makes it easier for people to override EXPORT_VALID_ARCHS to
# limit individual rules to a different set of architecture(s) from the overall
# build (such as machtest in QtCore).
simulator_and_device {
QMAKE_XARCH_CFLAGS =
QMAKE_XARCH_LFLAGS =
QMAKE_EXTRA_VARIABLES += QMAKE_XARCH_CFLAGS QMAKE_XARCH_LFLAGS

single_arch {
device_archs = $$first(device_archs)
simulator_archs = $$first(simulator_archs)
archs = $$first(archs)
}

for(arch, archs) {
contains(simulator_archs, $$arch) {
sdk = $$simulator.sdk
Expand Down Expand Up @@ -95,27 +103,30 @@ for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_
QMAKE_XARCH_LFLAGS_$${arch}
}

QMAKE_CFLAGS_USE_PRECOMPILE =
for(arch, archs) {
QMAKE_CFLAGS_USE_PRECOMPILE += \
-Xarch_$${arch} \
-include${QMAKE_PCH_OUTPUT_$${arch}}
}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE

QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT}
} else: osx {
version_identifier = macosx
deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET
QMAKE_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS)
QMAKE_CXXFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS)
QMAKE_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS)
} else {
simulator: \
version_identifier = $$simulator.deployment_identifier
else: \
version_identifier = $$device.deployment_identifier
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
QMAKE_CXXFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_MAC_SDK_PATH $$version_min_flag
}

QMAKE_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS)
QMAKE_CXXFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS)
QMAKE_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS)
# Enable precompiled headers for multiple architectures
QMAKE_CFLAGS_USE_PRECOMPILE =
for(arch, archs) {
QMAKE_CFLAGS_USE_PRECOMPILE += \
-Xarch_$${arch} \
-include${QMAKE_PCH_OUTPUT_$${arch}}
}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE

QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT}
}
2 changes: 1 addition & 1 deletion mkspecs/features/moc.prf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ win32:count(MOC_INCLUDEPATH, 40, >) {
# QNX's compiler sets "gcc" config, but does not support the -dM option;
# UIKit builds are always multi-arch due to simulator_and_device (unless
# -sdk is used) so this feature cannot possibly work.
if(gcc|intel_icl|msvc):!rim_qcc:!uikit {
if(gcc|intel_icl|msvc):!rim_qcc:!uikit:if(!macos|count(QMAKE_APPLE_DEVICE_ARCHS, 1)) {
moc_predefs.CONFIG = no_link
gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
Expand Down
6 changes: 5 additions & 1 deletion mkspecs/features/qt_configure.prf
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ defineTest(qtConfTest_compile) {
qmake_args += -qtconf $$system_quote($$QMAKE_QTCONF)

# Disable qmake features which are typically counterproductive for tests
qmake_args += "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\""
qmake_args += "\"CONFIG -= qt debug_and_release simulator app_bundle lib_bundle\""

# allow tests to behave differently depending on the type of library
# being built (shared/static). e.g. see config.tests/unix/icu
Expand All @@ -719,6 +719,10 @@ defineTest(qtConfTest_compile) {
# can work with a regular main() entry point on Windows.
qmake_configs += "console"

# for platforms with multiple architectures (macOS, iOS, tvOS, watchOS),
# make sure tests are only built for a single architecture
qmake_configs += "single_arch"

qmake_args += "\"CONFIG += $$qmake_configs\""

!$$host {
Expand Down
35 changes: 0 additions & 35 deletions mkspecs/features/uikit/default_post.prf
Original file line number Diff line number Diff line change
Expand Up @@ -67,38 +67,3 @@ macx-xcode {
}
}
}

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
}
19 changes: 0 additions & 19 deletions mkspecs/features/uikit/qt_config.prf

This file was deleted.

2 changes: 1 addition & 1 deletion mkspecs/features/uikit/sdk.prf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ contains(QMAKE_MAC_SDK, ^$${simulator.sdk}.*) {
CONFIG += simulator $${simulator.sdk}
}

build_pass:simulator: \
build_pass:!simulator_and_device:simulator: \
QMAKE_MAC_SDK ~= s,^$${device.sdk},$${simulator.sdk},

load(sdk)
Expand Down
2 changes: 2 additions & 0 deletions mkspecs/macx-clang/qmake.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9

QMAKE_APPLE_DEVICE_ARCHS = x86_64

include(../common/macx.conf)
include(../common/gcc-base-mac.conf)
include(../common/clang.conf)
Expand Down
2 changes: 2 additions & 0 deletions mkspecs/macx-g++/qmake.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ QMAKE_INCREMENTAL_STYLE = sublib

QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9

QMAKE_APPLE_DEVICE_ARCHS = x86_64

include(../common/macx.conf)
include(../common/gcc-base-mac.conf)
include(../common/g++-macx.conf)
Expand Down
11 changes: 8 additions & 3 deletions tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ OTHER_FILES += \
# Needs explicit load()ing due to aux template. Relies on QT being non-empty.
load(qt)

i386_d.target = good.i386.dylib
i386_d.depends = EXPORT_VALID_ARCHS=i386
i386.target = good.i386.dylib
i386.commands = $(CXX) $(CXXFLAGS) -shared -arch i386 -o $@ -I$(INCPATH) $<
i386.commands = $(CXX) $(CXXFLAGS) -shared -o $@ -I$(INCPATH) $<
i386.depends += $$PWD/../fakeplugin.cpp

x86_64_d.target = good.x86_64.dylib
x86_64_d.depends = EXPORT_VALID_ARCHS=x86_64
x86_64.target = good.x86_64.dylib
x86_64.commands = $(CXX) $(CXXFLAGS) -shared -arch x86_64 -o $@ -I$(INCPATH) $<
x86_64.commands = $(CXX) $(CXXFLAGS) -shared -o $@ -I$(INCPATH) $<
x86_64.depends += $$PWD/../fakeplugin.cpp

# Current Mac OS X toolchains have no compiler for PPC anymore
Expand Down Expand Up @@ -49,7 +54,7 @@ bad.depends += $$PWD/generate-bad.pl
MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \
fat_stub_i386 fat_stub_x86_64 bad
all.depends += $$MYTARGETS
QMAKE_EXTRA_TARGETS += $$MYTARGETS all
QMAKE_EXTRA_TARGETS += i386_d x86_64_d $$MYTARGETS all

QMAKE_CLEAN += $$i386.target $$x86_64.target $$ppc64.target $$fat_all.target \
$$fat_no_i386.target $$fat_no_x86_64.target \
Expand Down

0 comments on commit 28f5d79

Please sign in to comment.