summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/features/ios/qt.prf56
-rw-r--r--src/plugins/platforms/ios/ios.pro1
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.mm4
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm5
-rw-r--r--src/plugins/platforms/ios/qiosmain_dummy.mm56
-rw-r--r--src/plugins/platforms/ios/qiosmain_wrapper.mm13
6 files changed, 58 insertions, 77 deletions
diff --git a/mkspecs/features/ios/qt.prf b/mkspecs/features/ios/qt.prf
index 80d4907acd..f89cb0c287 100644
--- a/mkspecs/features/ios/qt.prf
+++ b/mkspecs/features/ios/qt.prf
@@ -17,8 +17,60 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) {
# need to generate an import for it.
CONFIG -= import_qpa_plugin
- # FIXME: Solve using 'ld -r -alias -unexported_symbol' instead
- !no_main_wrapper: DEFINES += main=qt_user_main
+ !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 use xcodebuild to resolve the location of the crt1 object file
+ # as we know that it lives in the same location as the c library.
+ c_library_path = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -find-library c 2>/dev/null")
+
+ # We also 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 = $$dirname(c_library_path)/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
+ }
}
load(qt)
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index 5a2129eb08..263577d43f 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -10,7 +10,6 @@ LIBS += -framework Foundation -framework UIKit -framework QuartzCore
OBJECTIVE_SOURCES = \
plugin.mm \
qiosmain_wrapper.mm \
- qiosmain_dummy.mm \
qiosintegration.mm \
qioswindow.mm \
qiosscreen.mm \
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
index 52d94f38fb..d4fd613ae3 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
@@ -46,7 +46,7 @@
#include <QtCore/QtCore>
-extern int qt_user_main(int argc, char *argv[]);
+extern "C" int main(int argc, char *argv[]);
@implementation QIOSApplicationDelegate
@@ -87,7 +87,7 @@ extern int qt_user_main(int argc, char *argv[]);
strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
- qt_user_main(argc, argv);
+ main(argc, argv);
delete[] argv;
}
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 7fd6015a2f..cbf9dba862 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -65,10 +65,7 @@ QIOSIntegration::QIOSIntegration()
<< "Error: You are creating QApplication before calling UIApplicationMain.\n"
<< "If you are writing a native iOS application, and only want to use Qt for\n"
<< "parts of the application, a good place to create QApplication is from within\n"
- << "'applicationDidFinishLaunching' inside your UIApplication delegate.\n"
- << "If you instead create a cross-platform Qt application and do not intend to call\n"
- << "UIApplicationMain, you need to link in libqtmain.a, and substitute main with qt_main.\n"
- << "This is normally done automatically by qmake.\n";
+ << "'applicationDidFinishLaunching' inside your UIApplication delegate.\n";
exit(-1);
}
diff --git a/src/plugins/platforms/ios/qiosmain_dummy.mm b/src/plugins/platforms/ios/qiosmain_dummy.mm
deleted file mode 100644
index 28d7e59381..0000000000
--- a/src/plugins/platforms/ios/qiosmain_dummy.mm
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
-
-/*
- This file provides a dummy implementation of qt_user_main, so that
- we don't get an undefined symbol in the hybrid use-case, where we
- don't rename main() to qt_user_main(). As long as the linker is not
- passed -all_load, this translation unit is only picked up and used
- if qt_user_main is not defined by the user's code.
-*/
-
-int qt_user_main(int, char **)
-{
- qFatal("Hit dummy qt_user_main, this should never happen!");
- return 0;
-}
diff --git a/src/plugins/platforms/ios/qiosmain_wrapper.mm b/src/plugins/platforms/ios/qiosmain_wrapper.mm
index d9b8c7311e..cb9a2c161e 100644
--- a/src/plugins/platforms/ios/qiosmain_wrapper.mm
+++ b/src/plugins/platforms/ios/qiosmain_wrapper.mm
@@ -41,18 +41,7 @@
#include "qiosapplicationdelegate.h"
-/*
- This file provides a wrapper implementation of main() for the non-
- hybrid use-case. The user's main is renamed to qt_user_main by the
- build rules, and we'll call out to that main at the appropriate time.
-
- This file purposly only exports a single symbol, _main, so that
- when the linker considers the translation unit for inclusion it
- will discard it when main has already been defined in the user's
- application for the hybrid use-case.
-*/
-
-int main(int argc, char *argv[])
+extern "C" int qtmn(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));