Generalize the winmain/qtmain entry-point library

The use-case is relevant for other platforms as well.

Now that Qt has a module system we can also replace a lot of the
hand crafted logic for linking with simpler constructs.

Change-Id: Ib6853aaf81bfea79c31f2de741d65b4b56f23ef6
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Tor Arne Vestbø 2020-10-15 17:04:27 +02:00
parent 8ec4fd9cff
commit b5af140809
16 changed files with 56 additions and 69 deletions

View File

@ -195,14 +195,14 @@ endfunction()
# This function records a dependency between ${main_target_name} and ${dep_target_name}
# at the CMake package level.
# E.g. Qt6CoreConfig.cmake needs to find_package(Qt6WinMain).
# E.g. Qt6CoreConfig.cmake needs to find_package(Qt6EntryPoint).
# main_target_name = Core
# dep_target_name = WinMain
# dep_target_name = EntryPoint
# This is just a convenience function that deals with Qt targets and their associated packages
# instead of raw package names.
function(qt_record_extra_qt_package_dependency main_target_name dep_target_name
dep_package_version)
# WinMain -> Qt6WinMain.
# EntryPoint -> Qt6EntryPoint.
qt_internal_module_info(qtfied_target_name "${dep_target_name}")
qt_record_extra_package_dependency("${main_target_name}" "${qtfied_target_name_versioned}"
"${dep_package_version}")

View File

@ -8,9 +8,9 @@
function(qt_internal_setup_startup_target)
set(dependent_target "Core")
# On windows, find_package(Qt6Core) should call find_package(Qt6WinMain) so that Startup can
# link against WinMain.
# On windows, find_package(Qt6Core) should call find_package(Qt6EntryPoint) so that Startup can
# link against EntryPoint.
if(WIN32)
qt_record_extra_qt_package_dependency("${dependent_target}" WinMain "${PROJECT_VERSION}")
qt_record_extra_qt_package_dependency("${dependent_target}" EntryPoint "${PROJECT_VERSION}")
endif()
endfunction()

View File

@ -63,7 +63,6 @@ QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
QMAKE_IDL = midl
QMAKE_LIB = $${CROSS_COMPILE}ar -rc

View File

@ -105,7 +105,6 @@ QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
QMAKE_LIBS_QT_ENTRY = -lqtmain
QMAKE_IDL = midl
QMAKE_LIB = lib /NOLOGO

View File

@ -0,0 +1,2 @@
qt:!console:contains(TEMPLATE, ".*app"): \
QT_PRIVATE += entrypoint

View File

@ -1,2 +1,2 @@
CONFIG = windows $$CONFIG
CONFIG = windows $$CONFIG entrypoint
load(default_pre)

View File

@ -3,8 +3,7 @@ build_pass:console {
warning("Remove 'console' from your CONFIG.")
}
# Do not link qtmain.lib
QMAKE_LIBS_QT_ENTRY =
CONFIG -= entrypoint
ACTIVEQT_VERSION = $$VERSION
isEmpty(ACTIVEQT_VERSION):ACTIVEQT_VERSION = 1.0

View File

@ -2,15 +2,4 @@ CONFIG -= console
QMAKE_LFLAGS += $$QMAKE_LFLAGS_WINDOWS
contains(TEMPLATE, ".*app") {
QMAKE_LFLAGS += $$QMAKE_LFLAGS_EXE
mingw:DEFINES += QT_NEEDS_QMAIN
qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) {
isEqual(entryLib, -lqtmain) {
lib = $$QT.core.libs/$${QMAKE_PREFIX_STATICLIB}qtmain$$QT_LIBINFIX$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB
PRE_TARGETDEPS += $$lib
QMAKE_LIBS += $$lib
} else {
QMAKE_LIBS += $${entryLib}
}
}
}

View File

@ -70,6 +70,6 @@ if(QT_FEATURE_gui AND QT_FEATURE_widgets)
endif()
add_subdirectory(plugins)
add_subdirectory(winmain)
add_subdirectory(entrypoint)
add_subdirectory(android)

View File

@ -1370,7 +1370,7 @@ function(_qt_internal_setup_startup_target)
set_target_properties("${target}" PROPERTIES "${initialized_prop}" TRUE)
endif()
# On Windows this enables automatic linkage to WinMain.
# On Windows this enables automatic linkage to QtEntryPoint.
# On iOS this enables automatic passing of a linker flag that will change the default
# entry point of the linked executable.
set(isExe "$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>")
@ -1378,7 +1378,7 @@ function(_qt_internal_setup_startup_target)
if(WIN32)
set(isWin32 "$<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>")
set(isPolicyNEW "$<TARGET_POLICY:CMP0020>")
set(finalGenex "$<$<AND:${isExe},${isWin32},${isNotExcluded},${isPolicyNEW}>:Qt::WinMain>")
set(finalGenex "$<$<AND:${isExe},${isWin32},${isNotExcluded},${isPolicyNEW}>:Qt::EntryPoint>")
# Use set_target_properties instead of target_link_libraries because the latter has some
# weird additional behavior of checking which project the target belongs to, and might

View File

@ -116,7 +116,7 @@
See \l{Qt Licensing} for further details.
Executables on Windows potentially link
against \l{The qtmain Library}. This library is available
against \l{The QtEntryPoint Library}. This library is available
under commercial licenses and also under the
\l{BSD 3-clause "New" or "Revised" License}.

View File

@ -4,7 +4,7 @@ if (NOT WIN32)
return()
endif()
qt_internal_add_module(WinMain
qt_internal_add_module(EntryPoint
STATIC
NO_SYNC_QT
NO_MODULE_HEADERS
@ -22,14 +22,12 @@ if (MSVC)
IN_CURRENT_SCOPE)
endif()
set_property(TARGET WinMain PROPERTY OUTPUT_NAME qtmain)
qt_internal_extend_target(WinMain CONDITION
SOURCES qtmain_win.cpp
qt_internal_extend_target(EntryPoint CONDITION WIN32
SOURCES qtentrypoint_win.cpp
LIBRARIES shell32
)
qt_internal_extend_target(WinMain CONDITION MINGW
qt_internal_extend_target(EntryPoint CONDITION MINGW
DEFINES QT_NEEDS_QMAIN
)
# special case end

View File

@ -0,0 +1,30 @@
# Additional Qt project file for QtEntryPoint lib
!win32:error("$$_FILE_ is intended only for Windows!")
TARGET = QtEntryPoint
CONFIG += static no_module_headers
QT = core
DEFINES += QT_NO_FOREACH
win32 {
SOURCES = qtentrypoint_win.cpp
CONFIG -= qt
QMAKE_USE_PRIVATE += shell32
msvc {
QMAKE_CFLAGS_DEBUG -= -Zi
QMAKE_CXXFLAGS_DEBUG -= -Zi
QMAKE_CFLAGS_DEBUG *= -Z7
QMAKE_CXXFLAGS_DEBUG *= -Z7
}
mingw {
DEFINES += QT_NEEDS_QMAIN
MODULE_DEFINES += QT_NEEDS_QMAIN
LIBS += -lmingw32
}
}
load(qt_module)

View File

@ -52,8 +52,8 @@
#include <shellapi.h>
/*
This file contains the code in the qtmain library for Windows.
qtmain contains the Windows startup code and is required for
This file contains the code in the QtEntryPoint library for Windows.
QtEntryPoint contains the Windows startup code and is required for
linking to the Qt DLL.
When a Windows application starts, the WinMain function is

View File

@ -64,9 +64,9 @@ src_tools_qvkgen.target = sub-qvkgen
force_bootstrap: src_tools_qvkgen.depends = src_tools_bootstrap
else: src_tools_qvkgen.depends = src_corelib
src_winmain.subdir = $$PWD/winmain
src_winmain.target = sub-winmain
src_winmain.depends = sub-corelib # just for the module .pri file
src_entrypoint.subdir = $$PWD/entrypoint
src_entrypoint.target = sub-entrypoint
src_entrypoint.depends = sub-corelib # just for the module .pri file
src_corelib.subdir = $$PWD/corelib
src_corelib.target = sub-corelib
@ -157,7 +157,9 @@ qtConfig(regularexpression):!qtConfig(system-pcre2):pcre2 {
}
TOOLS = src_tools_moc src_tools_rcc src_tools_tracegen src_tools_qlalr
SUBDIRS += src_corelib src_tools_qlalr
win32:SUBDIRS += src_winmain
win32:SUBDIRS += src_entrypoint
qtConfig(network) {
SUBDIRS += src_network
src_plugins.depends += src_network

View File

@ -1,31 +0,0 @@
# Additional Qt project file for qtmain lib on Windows
!win32:error("$$_FILE_ is intended only for Windows!")
TEMPLATE = lib
TARGET = qtmain
DESTDIR = $$QT.core.libs
CONFIG += static
QT = core
DEFINES += QT_NO_FOREACH
qtConfig(debug_and_release): CONFIG += build_all
msvc: QMAKE_CFLAGS_DEBUG -= -Zi
msvc: QMAKE_CXXFLAGS_DEBUG -= -Zi
msvc: QMAKE_CFLAGS_DEBUG *= -Z7
msvc: QMAKE_CXXFLAGS_DEBUG *= -Z7
mingw: DEFINES += QT_NEEDS_QMAIN
CONFIG -= qt
SOURCES = qtmain_win.cpp
QMAKE_USE_PRIVATE += shell32
load(qt_installs)
TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end
load(qt_targets)
load(qt_build_paths)
load(qt_common)