qt5base-lts/mkspecs/features/qt_module.prf
Thiago Macieira fff3101bc6 Place classes from private headers in the Qt_5_PRIVATE_API ELF version
This way, it's possible to tell which applications and libraries depend
on the Qt private API and of which Qt library. Linux distributions can
use this information to decide which applications need to be recompiled
every time Qt itself is rebuilt.

This is done by scanning all class and struct definitions in the private
headers (we've already got the list from syncqt). I opted to add a new
script instead of modifying syncqt because then this can run in parallel
with the rest of the compilation, as opposed to during qmake
time. Another advantage is that it catches modifications to the headers
in between qmake executions.

Since this is already Unix specific, it should be no problem to use Perl.

This solution is limited to use of non-inline symbols of classes
declared in private headers. It will not catch free variables (such as
qsimd_p.h's qt_cpu_features), use of inlined functions or just plain use
of a class/struct for accessing its data members. However, this is
already better than nothing and should help Linux distributions quite a
lot. And there's no way to catch the latter issue anyway.

Change-Id: I049a653beeb5454c9539ffff13e3fff36400ebbd
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2015-10-20 19:19:34 +00:00

288 lines
10 KiB
Plaintext

#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
!no_qt_module_warning:!contains(QMAKE_INTERNAL_INCLUDED_FILES, .*qmodule\\.pri) {
QMAKE_ACTUAL_PRO_FILE = $$basename(_PRO_FILE_)
isEmpty(QMAKE_ACTUAL_PRO_FILE): QMAKE_ACTUAL_PRO_FILE=.pro
warning("You should probably load(qt_build_config) first in $$QMAKE_ACTUAL_PRO_FILE for $$TARGET, as the latter also load()s qt_module.")
message("Not doing so may lead to qt_module.prf overriding compiler/linker options in your .pro file.")
message("Ignore this warning with CONFIG+=no_qt_module_warning if you know what you are doing.")
unset(QMAKE_ACTUAL_PRO_FILE)
}
load(qt_build_config) # loads qmodule.pri if hasn't been loaded already
isEmpty(MODULE):MODULE = $$section($$list($$basename(_PRO_FILE_)), ., 0, 0)
isEmpty(VERSION): VERSION = $$MODULE_VERSION
isEmpty(VERSION): error("Module does not define version.")
# Compile as shared/DLL or static according to the option given to configure
# unless overridden. Host builds are always static
host_build|staticlib: CONFIG += static
host_build {
QT -= gui # no host module will ever use gui
QMAKE_CFLAGS += $$QMAKE_CFLAGS_SPLIT_SECTIONS
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SPLIT_SECTIONS
force_bootstrap {
!build_pass: CONFIG += release
contains(QT, core(-private)?|xml) {
QT -= core core-private xml
QT += bootstrap-private
}
} else {
!build_pass:contains(QT_CONFIG, build_all): CONFIG += release
}
}
CONFIG += relative_qt_rpath # Qt libraries should be relocatable
ucmodule = $$upper($$MODULE)
isEmpty(MODULE_INCNAME): MODULE_INCNAME = $$TARGET
internal_module: \
MODULE_DEPENDS = $$replace(QT, -private$, _private)
else: \
MODULE_DEPENDS = $$replace(QT, -private$, )
MODULE_DEPENDS = $$unique(MODULE_DEPENDS)
contains(TARGET, QtAddOn.*): \
MODULE_DEFINE = QT_ADDON_$${ucmodule}_LIB
else: \
MODULE_DEFINE = QT_$${ucmodule}_LIB
MODULE_DEFINES = $$MODULE_DEFINE $$MODULE_DEFINES
load(qt_build_paths)
header_module {
TEMPLATE = aux
CONFIG += force_qt # Needed for the headers_clean tests.
} else {
TEMPLATE = lib
}
DESTDIR = $$MODULE_BASE_OUTDIR/lib
win32:!wince:!prefix_build: DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin
CONFIG += qmake_cache target_qt
QMAKE_DOCS_TARGETDIR = qt$${MODULE}
load(qt_module_pris)
load(qt_common)
!no_module_headers: load(qt_module_headers)
INCLUDEPATH *= $$eval(QT.$${MODULE}.includes) $$eval(QT.$${MODULE}_private.includes)
# If Qt was configured with -debug-and-release then build the module the same way
# - unless this is a host library
!host_build:if(win32|mac):!macx-xcode {
contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release
contains(QT_CONFIG, build_all):CONFIG += build_all
}
linux*:QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
QT += $$QT_FOR_PRIVATE
unset(QT_FOR_PRIVATE)
!internal_module:CONFIG += create_cmake
contains(TARGET, QtAddOn.*): \
DEFINES += QT_BUILD_ADDON_$${ucmodule}_LIB
else: \
DEFINES += QT_BUILD_$${ucmodule}_LIB
# OS X and iOS frameworks
mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
# Set the CFBundleIdentifier prefix for Qt frameworks
QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project
#QMAKE_FRAMEWORK_VERSION = 4.0
CONFIG += sliced_bundle qt_framework
header_module {
CONFIG += bundle
QMAKE_BUNDLE_EXTENSION = .framework
QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.lib
} else {
CONFIG += lib_bundle
}
CONFIG -= qt_install_headers #no need to install these as well
!debug_and_release|!build_all|CONFIG(release, debug|release) {
FRAMEWORK_HEADERS.version = Versions
FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES
FRAMEWORK_HEADERS.path = Headers
FRAMEWORK_PRIVATE_HEADERS.version = Versions
FRAMEWORK_PRIVATE_HEADERS.files = $$SYNCQT.PRIVATE_HEADER_FILES
FRAMEWORK_PRIVATE_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/private
FRAMEWORK_QPA_HEADERS.version = Versions
FRAMEWORK_QPA_HEADERS.files = $$SYNCQT.QPA_HEADER_FILES
FRAMEWORK_QPA_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/qpa
QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS FRAMEWORK_PRIVATE_HEADERS FRAMEWORK_QPA_HEADERS
}
}
mac {
CONFIG += explicitlib
macx-g++ {
QMAKE_CFLAGS += -fconstant-cfstrings
QMAKE_CXXFLAGS += -fconstant-cfstrings
}
contains(QT_CONFIG, rpath): \
QMAKE_SONAME_PREFIX = @rpath
}
DEFINES += QT_BUILDING_QT
win32 {
INCLUDEPATH += tmp
CONFIG += skip_target_version_ext
# If the code is really "unsafe" then it is unsafe on
# other platforms as well; so fixing these warnings just
# for MSVC builds, would clutter the code and wouldn't help
# in fixing issues that might exist on other platforms.
# Using the same functions across all supported platforms
# keeps the code clean and helps in writing code that is
# safe across all platforms.
DEFINES *= _CRT_SECURE_NO_WARNINGS
DEFINES += _USE_MATH_DEFINES
}
aix-g++* {
QMAKE_CFLAGS += -mminimal-toc
QMAKE_CXXFLAGS += -mminimal-toc
}
sse2:!contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):!host_build:!if(static:contains(QT_CONFIG, shared)) {
# If the compiler supports SSE2, enable it unconditionally in all of Qt shared libraries
# (and only the libraries). This is not expected to be a problem because:
# - on Windows, sharing of libraries is uncommon
# - on Mac OS X, all x86 CPUs already have SSE2 support (we won't even reach here)
# - on Linux, the dynamic loader can find the libraries on LIBDIR/sse2/
# The last guarantee does not apply to executables and plugins, so we can't enable for them.
QT_CPU_FEATURES.$$QT_ARCH += sse sse2
QMAKE_CFLAGS += $$QMAKE_CFLAGS_SSE2
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
}
clang {
apple_clang_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
reg_clang_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION}
!lessThan(apple_clang_ver, "5.1")|!lessThan(reg_clang_ver, "3.4"): \
CONFIG += compiler_supports_fpmath
} else: gcc {
CONFIG += compiler_supports_fpmath
}
equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_supports_fpmath {
# Turn on SSE-based floating-point math
QMAKE_CFLAGS += -mfpmath=sse
QMAKE_CXXFLAGS += -mfpmath=sse
}
unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static {
verscript = $$OUT_PWD/$${TARGET}.version
QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript
internal_module {
verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API { *; };"
} else {
verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API {" \
" qt_private_api_tag*;" "@CLASSLIST@" "};"
current = Qt_$$QT_MAJOR_VERSION
verscript_content += "$$current { *; };"
isEmpty(QT_NAMESPACE): tag_symbol = qt_version_tag
else: tag_symbol = qt_version_tag_$$QT_NAMESPACE
for(i, 0..$$QT_MINOR_VERSION) {
previous = $$current
current = Qt_$${QT_MAJOR_VERSION}.$$i
equals(i, $$QT_MINOR_VERSION): verscript_content += "$$current { $$tag_symbol; } $$previous;"
else: verscript_content += "$$current {} $$previous;"
}
# Add a post-processing step to replace the @CLASSLIST@
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $^ > $@
verscriptprocess.target = $$verscript
verscriptprocess.depends = $${verscript}.in
for(header, SYNCQT.PRIVATE_HEADER_FILES): \
verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header
QMAKE_EXTRA_TARGETS += verscriptprocess
PRE_TARGETDEPS += $$verscript
verscript = $${verscript}.in
}
write_file($$verscript, verscript_content)|error("Aborting.")
unset(current)
unset(previous)
unset(verscript)
unset(verscript_content)
}
android: CONFIG += qt_android_deps
#install directives
load(qt_installs)
load(qt_targets)
# this builds on top of qt_common
unix|mingw {
CONFIG += create_pc
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
host_build: \
QMAKE_PKGCONFIG_LIBDIR = $$[QT_HOST_LIBS]
else: \
QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS/raw]
QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ")
QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)
for(i, MODULE_DEPENDS): \
QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$eval(QT.$${i}.MAJOR_VERSION))
isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \
QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module
pclib_replace.match = $$lib_replace.match
!isEmpty(lib_replace.replace): \
pclib_replace.replace = $$QMAKE_PKGCONFIG_LIBDIR
pclib_replace.CONFIG = path
QMAKE_PKGCONFIG_INSTALL_REPLACE += pclib_replace
unix {
CONFIG += create_libtool explicitlib
host_build: \
QMAKE_LIBTOOL_LIBDIR = $$[QT_HOST_LIBS]
else: \
QMAKE_LIBTOOL_LIBDIR = "=$$[QT_INSTALL_LIBS/raw]"
ltlib_replace.match = $$lib_replace.match
!isEmpty(lib_replace.replace): \
ltlib_replace.replace = $$QMAKE_LIBTOOL_LIBDIR
ltlib_replace.CONFIG = path
QMAKE_LIBTOOL_INSTALL_REPLACE += ltlib_replace
}
}
contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
DEFINES *= QT_NO_CAST_TO_ASCII QT_ASCII_CAST_WARNINGS
DEFINES *= QT_MOC_COMPAT #we don't need warnings from calling moc code in our generated code
DEFINES *= QT_USE_QSTRINGBUILDER
DEFINES *= QT_DEPRECATED_WARNINGS
win32 {
# On Windows, due to the way DLLs work, we need to export all functions,
# including the inlines
DEFINES *= QT_DISABLE_DEPRECATED_BEFORE=0x040800
} else {
# On other platforms, Qt's own compilation goes needs to compile the Qt 5.0 API
DEFINES *= QT_DISABLE_DEPRECATED_BEFORE=0x050000
}
TARGET = $$qt5LibraryTarget($$TARGET$$QT_LIBINFIX) # Do this towards the end