Automatically link to the qtmain library when linking to QtCore.

When using QAxServer, ensure that the qtmain library is excluded
by reporting an error at CMake time if it is not.
This commit is contained in:
Stephen Kelly 2012-11-20 14:53:41 +01:00 committed by Brad King
parent 6c8d8afe34
commit e3b5eb6b23
8 changed files with 122 additions and 6 deletions

View File

@ -65,6 +65,12 @@
# is much more flexible, but requires that FindQt4.cmake is executed before # is much more flexible, but requires that FindQt4.cmake is executed before
# such an exported dependency file is processed. # such an exported dependency file is processed.
# #
# Note that if using IMPORTED targets, the qtmain.lib static library is
# automatically linked on Windows. To disable that globally, set the
# QT4_NO_LINK_QTMAIN variable before finding Qt4. To disable that for a
# particular executable, set the QT4_NO_LINK_QTMAIN target property to
# True on the executable.
#
# QT_INCLUDE_DIRS_NO_SYSTEM # QT_INCLUDE_DIRS_NO_SYSTEM
# If this variable is set to TRUE, the Qt include directories # If this variable is set to TRUE, the Qt include directories
# in the QT_USE_FILE will NOT have the SYSTEM keyword set. # in the QT_USE_FILE will NOT have the SYSTEM keyword set.
@ -1009,7 +1015,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
# platform dependent libraries # platform dependent libraries
if(Q_WS_WIN) if(Q_WS_WIN)
_QT4_ADJUST_LIB_VARS(qtmain) _QT4_ADJUST_LIB_VARS(qtmain)
_QT4_ADJUST_LIB_VARS(QAxServer) _QT4_ADJUST_LIB_VARS(QAxServer)
set_property(TARGET Qt4::QAxServer PROPERTY
INTERFACE_QT4_NO_LINK_QTMAIN ON
)
set_property(TARGET Qt4::QAxServer APPEND PROPERTY
COMPATIBLE_INTERFACE_BOOL QT4_NO_LINK_QTMAIN)
_QT4_ADJUST_LIB_VARS(QAxContainer) _QT4_ADJUST_LIB_VARS(QAxContainer)
endif() endif()
@ -1049,6 +1062,21 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
_qt4_add_target_private_depends(phonon DBus) _qt4_add_target_private_depends(phonon DBus)
endif() endif()
if (WIN32 AND NOT QT4_NO_LINK_QTMAIN)
set(_isExe $<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>)
set(_isWin32 $<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>)
set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:QT4_NO_LINK_QTMAIN>>>)
set(_isPolicyNEW $<TARGET_POLICY:CMP0020>)
set_property(TARGET Qt4::QtCore APPEND PROPERTY
IMPORTED_LINK_INTERFACE_LIBRARIES
$<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt4::qtmain>
)
unset(_isExe)
unset(_isWin32)
unset(_isNotExcluded)
unset(_isPolicyNEW)
endif()
####################################### #######################################
# #
# Check the executables of Qt # Check the executables of Qt

View File

@ -492,6 +492,7 @@ static const char* targetPolicyWhitelist[] = {
"CMP0003" "CMP0003"
, "CMP0004" , "CMP0004"
, "CMP0008" , "CMP0008"
, "CMP0020"
}; };
cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy) cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
@ -505,6 +506,7 @@ cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
RETURN_POLICY(CMP0003) RETURN_POLICY(CMP0003)
RETURN_POLICY(CMP0004) RETURN_POLICY(CMP0004)
RETURN_POLICY(CMP0008) RETURN_POLICY(CMP0008)
RETURN_POLICY(CMP0020)
#undef RETURN_POLICY #undef RETURN_POLICY
@ -523,6 +525,7 @@ cmPolicies::PolicyID policyForString(const char *policy_id)
RETURN_POLICY_ID(CMP0003) RETURN_POLICY_ID(CMP0003)
RETURN_POLICY_ID(CMP0004) RETURN_POLICY_ID(CMP0004)
RETURN_POLICY_ID(CMP0008) RETURN_POLICY_ID(CMP0008)
RETURN_POLICY_ID(CMP0020)
#undef RETURN_POLICY_ID #undef RETURN_POLICY_ID
@ -575,8 +578,8 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
} }
reportError(context, content->GetOriginalExpression(), reportError(context, content->GetOriginalExpression(),
"$<TARGET_POLICY:prop> may only be used with a limited number of " "$<TARGET_POLICY:prop> may only be used with a limited number of "
"policies. Currently it may be used with policies CMP0003, CMP0004 " "policies. Currently it may be used with policies CMP0003, CMP0004, "
"and CMP0008." "CMP0008 and CMP0020."
); );
return std::string(); return std::string();
} }

View File

@ -508,6 +508,27 @@ cmPolicies::cmPolicies()
"for strict compatibility. " "for strict compatibility. "
"The NEW behavior for this policy is to leave the values untouched.", "The NEW behavior for this policy is to leave the values untouched.",
2,8,11,0, cmPolicies::WARN); 2,8,11,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0020, "CMP0020",
"Automatically link Qt executables to qtmain target on Windows.",
"CMake 2.8.10 and lower required users of Qt to always specify a link "
"dependency to the qtmain.lib static library manually on Windows. CMake "
"2.8.11 gained the ability to evaluate generator expressions while "
"determining the link dependencies from IMPORTED targets. This allows "
"CMake itself to automatically link executables which link to Qt to the "
"qtmain.lib library when using IMPORTED Qt targets. For applications "
"already linking to qtmain.lib, this should have little impact. For "
"applications which supply their own alternative WinMain implementation "
"and for applications which use the QAxServer library, this automatic "
"linking will need to be disabled as per the documentation."
"\n"
"The OLD behavior for this policy is not to link executables to "
"qtmain.lib automatically when they link to the QtCore IMPORTED"
"target. "
"The NEW behavior for this policy is to link executables to "
"qtmain.lib automatically when they link to QtCore IMPORTED target.",
2,8,11,0, cmPolicies::WARN);
} }
cmPolicies::~cmPolicies() cmPolicies::~cmPolicies()

View File

@ -69,6 +69,7 @@ public:
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C} /// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
/// instead. /// instead.
CMP0019, ///< No variable re-expansion in include and link info CMP0019, ///< No variable re-expansion in include and link info
CMP0020, ///< Automatically link Qt executables to qtmain target
/** \brief Always the last entry. /** \brief Always the last entry.
* *

View File

@ -145,6 +145,7 @@ cmTarget::cmTarget()
this->PolicyStatusCMP0003 = cmPolicies::WARN; this->PolicyStatusCMP0003 = cmPolicies::WARN;
this->PolicyStatusCMP0004 = cmPolicies::WARN; this->PolicyStatusCMP0004 = cmPolicies::WARN;
this->PolicyStatusCMP0008 = cmPolicies::WARN; this->PolicyStatusCMP0008 = cmPolicies::WARN;
this->PolicyStatusCMP0020 = cmPolicies::WARN;
this->LinkLibrariesAnalyzed = false; this->LinkLibrariesAnalyzed = false;
this->HaveInstallRule = false; this->HaveInstallRule = false;
this->DLLPlatform = false; this->DLLPlatform = false;
@ -1499,6 +1500,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->Makefile->GetPolicyStatus(cmPolicies::CMP0004); this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
this->PolicyStatusCMP0008 = this->PolicyStatusCMP0008 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0008); this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
this->PolicyStatusCMP0020 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0020);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -102,6 +102,10 @@ public:
cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
{ return this->PolicyStatusCMP0008; } { return this->PolicyStatusCMP0008; }
/** Get the status of policy CMP0020 when the target was created. */
cmPolicies::PolicyStatus GetPolicyStatusCMP0020() const
{ return this->PolicyStatusCMP0020; }
/** /**
* Get the list of the custom commands for this target * Get the list of the custom commands for this target
*/ */
@ -656,6 +660,7 @@ private:
cmPolicies::PolicyStatus PolicyStatusCMP0003; cmPolicies::PolicyStatus PolicyStatusCMP0003;
cmPolicies::PolicyStatus PolicyStatusCMP0004; cmPolicies::PolicyStatus PolicyStatusCMP0004;
cmPolicies::PolicyStatus PolicyStatusCMP0008; cmPolicies::PolicyStatus PolicyStatusCMP0008;
cmPolicies::PolicyStatus PolicyStatusCMP0020;
// Internal representation details. // Internal representation details.
friend class cmTargetInternals; friend class cmTargetInternals;

View File

@ -2,15 +2,16 @@ cmake_minimum_required(VERSION 2.8)
project(Qt4Targets) project(Qt4Targets)
cmake_policy(SET CMP0020 NEW)
find_package(Qt4 REQUIRED) find_package(Qt4 REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(Qt4Targets WIN32 main.cpp) add_executable(Qt4Targets WIN32 main.cpp)
target_link_libraries(Qt4Targets Qt4::QtGui) target_link_libraries(Qt4Targets Qt4::QtGui)
if (WIN32)
target_link_libraries(Qt4Targets Qt4::qtmain)
endif()
set_property(TARGET Qt4Targets APPEND PROPERTY set_property(TARGET Qt4Targets APPEND PROPERTY
INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
@ -19,3 +20,21 @@ set_property(TARGET Qt4Targets APPEND PROPERTY
COMPILE_DEFINITIONS COMPILE_DEFINITIONS
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS> $<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS>
) )
if (WIN32)
if (TARGET Qt4::QAxServer)
add_executable(activeqtexe WIN32 activeqtexe.cpp)
set_property(TARGET activeqtexe PROPERTY QT4_NO_LINK_QTMAIN ON)
target_link_libraries(activeqtexe Qt4::QAxServer Qt4::QtGui)
set_property(TARGET activeqtexe APPEND PROPERTY
INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:Qt4::QAxServer,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
)
set_property(TARGET activeqtexe APPEND PROPERTY
COMPILE_DEFINITIONS
$<TARGET_PROPERTY:Qt4::QAxServer,INTERFACE_COMPILE_DEFINITIONS>
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS>
)
endif()
endif()

View File

@ -0,0 +1,36 @@
#include <QApplication>
#ifndef QT_QAXSERVER_LIB
#error Expected QT_QAXSERVER_LIB
#endif
#include <QAxFactory>
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = 0)
: QObject(parent)
{
}
};
QAXFACTORY_DEFAULT(MyObject,
"{4dc3f340-a6f7-44e4-a79b-3e9217685fbd}",
"{9ee49617-7d5c-441a-b833-4b068d41d751}",
"{13eca64b-ee2a-4f3c-aa04-5d9d975779a7}",
"{ce947ee3-0403-4fdc-895a-4fe779344b46}",
"{8de435ce-8d2a-46ac-b3b3-cb800d0547c7}");
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QAxFactory::isServer();
return app.exec();
}
#include "activeqtexe.moc"