Introduce OBJECTIVE_HEADERS

When a ObjC++ QObject subclass is listed in the regular HEADERS, qmake
creates a .cpp file. The moc file will then fail to compile, as it
requries ObjC++ headers. Using Q_FORWARD_DECLARE_OBJC_CLASS() can be
used to let the class be parsed by The compiler, but link will still
fail, as the generated methods (e.g. signals) must be built with ObjC++
compiler, in case they have ObjC parameters:

 Q_FORWARD_DECLARE_OBJC_CLASS(NSString);

 class MyClass: public QObject {
     Q_OBJECT
 signals:
     void objcSignal(NSString * myObj);
 };

The canonical workaround for that is including the .cpp file into the
corresponding .mm file. This also offers a compilation speed advantage,
but is somewhat counter-intuitive.

Therefore, we introduce a separate variable which instructs moc to create
.mm files directly.

Task-number: QTBUG-1581
Change-Id: Ia98af58006efd168ea37f3a63c396979e7e81baa
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
bb10
Francois Ferrand 2016-10-06 12:07:29 +02:00
parent a980250a66
commit fabedd399e
2 changed files with 40 additions and 2 deletions

View File

@ -76,6 +76,19 @@ silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands
QMAKE_EXTRA_COMPILERS += moc_header
INCREDIBUILD_XGE += moc_header
#moc objc headers
moc_objc_header.CONFIG = moc_verify
moc_objc_header.dependency_type = TYPE_C
moc_objc_header.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
moc_objc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJCXX)}
moc_objc_header.input = OBJECTIVE_HEADERS
moc_objc_header.variable_out = SOURCES
moc_objc_header.name = MOC ${QMAKE_FILE_IN}
moc_objc_header.depends += $$WIN_INCLUDETEMP $$moc_predefs.output
silent:moc_objc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_objc_header.commands
QMAKE_EXTRA_COMPILERS += moc_objc_header
INCREDIBUILD_XGE += moc_objc_header
#moc sources
moc_source.CONFIG = no_link moc_verify
moc_source.dependency_type = TYPE_C
@ -95,14 +108,15 @@ INCLUDEPATH += $$absolute_path($$MOC_DIR, $$OUT_PWD)
!no_mocdepend {
moc_source.depends += $$QMAKE_MOC_EXE
moc_header.depends += $$QMAKE_MOC_EXE
moc_objc_header.depends += $$QMAKE_MOC_EXE
}
#generate a mocclean
build_pass|isEmpty(BUILDS):mocclean.depends = compiler_moc_header_clean compiler_moc_source_clean
build_pass|isEmpty(BUILDS):mocclean.depends = compiler_moc_header_clean compiler_moc_objc_header_clean compiler_moc_source_clean
else:mocclean.CONFIG += recursive
QMAKE_EXTRA_TARGETS += mocclean
#generate a mocables
build_pass|isEmpty(BUILDS):mocables.depends = compiler_moc_header_make_all compiler_moc_source_make_all
build_pass|isEmpty(BUILDS):mocables.depends = compiler_moc_header_make_all compiler_moc_objc_header_make_all compiler_moc_source_make_all
else:mocables.CONFIG += recursive
QMAKE_EXTRA_TARGETS += mocables

View File

@ -1324,6 +1324,30 @@
\snippet code/doc_src_qmake-manual.pro 40
\target OBJECTIVE_HEADERS
\section1 OBJECTIVE_HEADERS
Defines the Objective-C++ header files for the project.
qmake automatically detects whether \l{moc} is required by the classes in the
headers, and adds the appropriate dependencies and files to the project for
generating and linking the moc files.
This is similar to the HEADERS variable, but will let the generated moc
files be compiled with the Objective-C++ compiler.
See also \l{#OBJECTIVE_SOURCES}{OBJECTIVE_SOURCES}.
\target OBJECTIVE_SOURCES
\section1 OBJECTIVE_SOURCES
Specifies the names of all Objective-C/C++ source files in the project.
This variable is now obsolete, Objective-C/C++ files (.m and .mm) can be
added to the \l{#SOURCES}{SOURCES} variable.
See also \l{#OBJECTIVE_HEADERS}{OBJECTIVE_HEADERS}.
\target OBJECTS
\section1 OBJECTS