summaryrefslogtreecommitdiffstats
path: root/mkspecs/macx-ios-clang/features/qt.prf
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-10-16 19:06:47 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-17 13:26:28 +0200
commit32f34ddbe1a57255194703955730058386789cf8 (patch)
treee576bbc3e81a42ecf8064d7f533e43dc5afce1a8 /mkspecs/macx-ios-clang/features/qt.prf
parentb5fe1ed1724a34765a91faa135b2dd98e1941f58 (diff)
iOS: Wrap user's main by renaming symbol and relying on weak linking
This approach is similar to the earlier apprach of defining main=qt_main when building the user's sources, but uses the linker to rename the symbol instead, which is less fragile than using the preprocessor. To keep the hybrid usecase unaffected by our wrapper logic we declare both our main wrapper and a fallback qt_main as weak symbols, which ensures that when the user's application links in our plugin the real main/qt_main provided by the user is preferred over our weak symbols. Change-Id: Ic76f3ba8932430c4b13a1d3a40b8ed2322fe5eea Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'mkspecs/macx-ios-clang/features/qt.prf')
-rw-r--r--mkspecs/macx-ios-clang/features/qt.prf76
1 files changed, 25 insertions, 51 deletions
diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf
index 9fa882c99f..2897c62819 100644
--- a/mkspecs/macx-ios-clang/features/qt.prf
+++ b/mkspecs/macx-ios-clang/features/qt.prf
@@ -1,8 +1,5 @@
equals(TEMPLATE, app):contains(QT, gui(-private)?) {
- !macx-xcode: \
- error("Linking the iOS platform plugin requires bulding through Xcode")
-
LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
lib_name = qios
@@ -21,54 +18,31 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) {
CONFIG -= import_qpa_plugin
!no_main_wrapper {
- # Instead of messing with the user's main function we go the other
- # way and change the application entry point to call our main wrapper.
- # This entry point is the 'start' symbol, provided by crt1.o, so we
- # make a copy of the file and rename the '_main' unresolved symbol
- # to our wrapper function, '_qtmn', injecting ourselves into the app
- # startup. Once Apple starts shipping the LLVM linker (lld) we may
- # get rid of this step completely and just pass -e _qtmn to the
- # linker, taking advantage of the new LC_MAIN load command.
-
- # We know that iOS 3.1 and up uses crt1.3.1.o (technically not
- # true for simulator, but the SDK has a symlink to the correct file).
- original_crt_path = "$(SDK_DIR)/usr/lib/crt1.3.1.o"
-
- xcode_objects_path = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)"
- custom_crt_filename = "crt1_qt.o"
- custom_crt_path = "$$xcode_objects_path/$$custom_crt_filename"
-
- EOC = $$escape_expand(\\n\\t)
- create_custom_crt.commands = \
- # Copy original crt1 to build directory
- "$$QMAKE_COPY_FILE $$original_crt_path $$custom_crt_path $$EOC" \
- # And rename all occurrences of _main to _qtmn
- "strings -t d - $${custom_crt_path}" \
- "| sed -n 's/^\\([0-9]\\{1,\\}\\) _main\$\$/\1/p'" \
- "| while read offset; do" \
- "printf '_qtmn'" \
- "| dd of=$${custom_crt_path} bs=1 seek=\$\$offset conv=notrunc >/dev/null 2>&1" \
- "; done"
- create_custom_crt.depends = $$original_crt_path
- create_custom_crt.target = $$custom_crt_path
- preprocess.depends = create_custom_crt
- QMAKE_EXTRA_TARGETS += create_custom_crt preprocess
-
- clean_custom_crt.commands = "$$QMAKE_DEL_FILE $$custom_crt_path"
- preprocess_clean.depends += clean_custom_crt
- QMAKE_EXTRA_TARGETS += clean_custom_crt preprocess_clean
-
- # Prevent usage of new LC_MAIN load command, which skips start/crt1
- # and calls main from the loader. We rely on injecting into start.
- QMAKE_LFLAGS += -Wl,-no_new_main
-
- # Explicitly link against our modified crt1 object
- QMAKE_LFLAGS += -nostartfiles -l$${custom_crt_filename}
-
- # Workaround for QMAKE_PBX_LIBPATHS mangling the Xcode variables
- lib_search_path.name = LIBRARY_SEARCH_PATHS
- lib_search_path.value = $$xcode_objects_path
- QMAKE_MAC_XCODE_SETTINGS += lib_search_path
+ # We use ld to rename the _main symbol to _qt_main, so that we don't get a symbol clash
+ # with the _main we provide that calls UIApplicationMain. We need to make a copy of the
+ # original object file, as ld will not copy over DWARF debug information to the output
+ # file. Instead, it will inject a reference back to the original object file, so when
+ # Xcode runs dsymutil to make the final dSYM file it will still find the debug info
+ # for the object file that provided the original _main. This back-reference has the
+ # interesting side-effect of the debug information still referring to the original
+ # symbol name, so stack-traces will show both our wrapper main and the original
+ # user main as 'main', and adding a symbolic breakpoint for 'main' will break on
+ # both functions. Although a bit weird, it's a good thing, as the user will still be
+ # able to add symbolic breakpoints for 'main', not caring that the symbol is actually
+ # called 'qt_main' now.
+
+ isEmpty(OBJECTS_DIR): \
+ OBJECTS_DIR = .
+
+ !isEmpty(QMAKE_PRE_LINK): \
+ QMAKE_PRE_LINK += ";"
+
+ QMAKE_PRE_LINK += \
+ "for f in $(find $${OBJECTS_DIR} -name '*.o'); do" \
+ "(nm $f | grep -q 'T _main' && cp $f $f.original" \
+ "&& ld -r -alias _main _qt_main -unexported_symbol _main $f.original -o $f)" \
+ "|| true" \
+ "; done"
}
}