Merge topic 'qt4-autolink-qtmain'
e3b5eb6
Automatically link to the qtmain library when linking to QtCore.6c8d8af
Add the $<TARGET_POLICY> expression
This commit is contained in:
commit
a37b0e3ebf
|
@ -65,6 +65,12 @@
|
|||
# is much more flexible, but requires that FindQt4.cmake is executed before
|
||||
# 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
|
||||
# If this variable is set to TRUE, the Qt include directories
|
||||
# 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
|
||||
if(Q_WS_WIN)
|
||||
_QT4_ADJUST_LIB_VARS(qtmain)
|
||||
|
||||
_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)
|
||||
endif()
|
||||
|
||||
|
@ -1049,6 +1062,21 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
_qt4_add_target_private_depends(phonon DBus)
|
||||
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
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
" $<TARGET_PROPERTY:tgt,prop> = The value of the property prop\n" \
|
||||
"on the target tgt. Note that tgt is not added as a dependency of\n" \
|
||||
"the target this expression is evaluated on.\n" \
|
||||
" $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \
|
||||
"the 'head' target was created, else '0'. If the policy was not " \
|
||||
"set, the warning message for the policy will be emitted. This " \
|
||||
"generator expression only works for a subset of policies.\n" \
|
||||
"Boolean expressions:\n" \
|
||||
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
|
||||
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
|
||||
|
|
|
@ -508,6 +508,105 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
|
|||
|
||||
} targetNameNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* targetPolicyWhitelist[] = {
|
||||
"CMP0003"
|
||||
, "CMP0004"
|
||||
, "CMP0008"
|
||||
, "CMP0020"
|
||||
};
|
||||
|
||||
cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
|
||||
{
|
||||
#define RETURN_POLICY(POLICY) \
|
||||
if (strcmp(policy, #POLICY) == 0) \
|
||||
{ \
|
||||
return tgt->GetPolicyStatus ## POLICY (); \
|
||||
} \
|
||||
|
||||
RETURN_POLICY(CMP0003)
|
||||
RETURN_POLICY(CMP0004)
|
||||
RETURN_POLICY(CMP0008)
|
||||
RETURN_POLICY(CMP0020)
|
||||
|
||||
#undef RETURN_POLICY
|
||||
|
||||
assert("!Unreachable code. Not a valid policy");
|
||||
return cmPolicies::WARN;
|
||||
}
|
||||
|
||||
cmPolicies::PolicyID policyForString(const char *policy_id)
|
||||
{
|
||||
#define RETURN_POLICY_ID(POLICY_ID) \
|
||||
if (strcmp(policy_id, #POLICY_ID) == 0) \
|
||||
{ \
|
||||
return cmPolicies:: POLICY_ID; \
|
||||
} \
|
||||
|
||||
RETURN_POLICY_ID(CMP0003)
|
||||
RETURN_POLICY_ID(CMP0004)
|
||||
RETURN_POLICY_ID(CMP0008)
|
||||
RETURN_POLICY_ID(CMP0020)
|
||||
|
||||
#undef RETURN_POLICY_ID
|
||||
|
||||
assert("!Unreachable code. Not a valid policy");
|
||||
return cmPolicies::CMP0002;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct TargetPolicyNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetPolicyNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context ,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
if (!context->HeadTarget)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<TARGET_POLICY:prop> may only be used with targets. It may not "
|
||||
"be used with add_custom_command.");
|
||||
return std::string();
|
||||
}
|
||||
for (size_t i = 0;
|
||||
i < (sizeof(targetPolicyWhitelist) /
|
||||
sizeof(*targetPolicyWhitelist));
|
||||
++i)
|
||||
{
|
||||
const char *policy = targetPolicyWhitelist[i];
|
||||
if (parameters.front() == policy)
|
||||
{
|
||||
cmMakefile *mf = context->HeadTarget->GetMakefile();
|
||||
switch(statusForTarget(context->HeadTarget, policy))
|
||||
{
|
||||
case cmPolicies::WARN:
|
||||
mf->IssueMessage(cmake::AUTHOR_WARNING,
|
||||
mf->GetPolicies()->
|
||||
GetPolicyWarning(policyForString(policy)));
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::OLD:
|
||||
return "0";
|
||||
case cmPolicies::NEW:
|
||||
return "1";
|
||||
}
|
||||
}
|
||||
}
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<TARGET_POLICY:prop> may only be used with a limited number of "
|
||||
"policies. Currently it may be used with policies CMP0003, CMP0004, "
|
||||
"CMP0008 and CMP0020."
|
||||
);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
} targetPolicyNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<bool linker, bool soname>
|
||||
struct TargetFilesystemArtifactResultCreator
|
||||
|
@ -735,6 +834,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
return &targetPropertyNode;
|
||||
else if (identifier == "TARGET_NAME")
|
||||
return &targetNameNode;
|
||||
else if (identifier == "TARGET_POLICY")
|
||||
return &targetPolicyNode;
|
||||
else if (identifier == "BUILD_INTERFACE")
|
||||
return &buildInterfaceNode;
|
||||
else if (identifier == "INSTALL_INTERFACE")
|
||||
|
|
|
@ -508,6 +508,27 @@ cmPolicies::cmPolicies()
|
|||
"for strict compatibility. "
|
||||
"The NEW behavior for this policy is to leave the values untouched.",
|
||||
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()
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
|
||||
/// instead.
|
||||
CMP0019, ///< No variable re-expansion in include and link info
|
||||
CMP0020, ///< Automatically link Qt executables to qtmain target
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -145,6 +145,7 @@ cmTarget::cmTarget()
|
|||
this->PolicyStatusCMP0003 = cmPolicies::WARN;
|
||||
this->PolicyStatusCMP0004 = cmPolicies::WARN;
|
||||
this->PolicyStatusCMP0008 = cmPolicies::WARN;
|
||||
this->PolicyStatusCMP0020 = cmPolicies::WARN;
|
||||
this->LinkLibrariesAnalyzed = false;
|
||||
this->HaveInstallRule = false;
|
||||
this->DLLPlatform = false;
|
||||
|
@ -1499,6 +1500,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
|||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
|
||||
this->PolicyStatusCMP0008 =
|
||||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
|
||||
this->PolicyStatusCMP0020 =
|
||||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0020);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -102,6 +102,10 @@ public:
|
|||
cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
|
||||
{ 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
|
||||
*/
|
||||
|
@ -658,6 +662,7 @@ private:
|
|||
cmPolicies::PolicyStatus PolicyStatusCMP0003;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0004;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0008;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0020;
|
||||
|
||||
// Internal representation details.
|
||||
friend class cmTargetInternals;
|
||||
|
|
|
@ -2,15 +2,16 @@ cmake_minimum_required(VERSION 2.8)
|
|||
|
||||
project(Qt4Targets)
|
||||
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
|
||||
find_package(Qt4 REQUIRED)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_executable(Qt4Targets WIN32 main.cpp)
|
||||
target_link_libraries(Qt4Targets Qt4::QtGui)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(Qt4Targets Qt4::qtmain)
|
||||
endif()
|
||||
|
||||
set_property(TARGET Qt4Targets APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
|
@ -19,3 +20,21 @@ set_property(TARGET Qt4Targets APPEND PROPERTY
|
|||
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()
|
||||
|
|
|
@ -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"
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,2 @@
|
|||
Target "foo" links to item " bar " which has leading or trailing
|
||||
whitespace. This is now an error according to policy CMP0004.
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
cmake_policy(SET CMP0004 NEW)
|
||||
|
||||
add_library(foo SHARED empty.cpp)
|
||||
add_library(bar SHARED empty.cpp)
|
||||
|
||||
target_link_libraries(foo "$<1: bar >")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,2 @@
|
|||
Target "bat" links to item " bar " which has leading or trailing
|
||||
whitespace. This is now an error according to policy CMP0004.
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
cmake_policy(SET CMP0004 OLD)
|
||||
|
||||
add_library(foo SHARED empty.cpp)
|
||||
add_library(bar SHARED empty.cpp)
|
||||
add_library(bing SHARED empty.cpp)
|
||||
add_library(bung SHARED empty.cpp)
|
||||
|
||||
cmake_policy(SET CMP0004 NEW)
|
||||
|
||||
add_library(bat SHARED empty.cpp)
|
||||
|
||||
target_link_libraries(foo "$<1: bar >")
|
||||
target_link_libraries(bing "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
|
||||
target_link_libraries(bung "$<$<TARGET_POLICY:CMP0004>: bar >")
|
||||
|
||||
# The line below causes the error because the policy is NEW when bat
|
||||
# is created.
|
||||
target_link_libraries(bat "$<1: bar >")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,2 @@
|
|||
Target "foo" links to item " bat " which has leading or trailing
|
||||
whitespace. This is now an error according to policy CMP0004.
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
cmake_policy(SET CMP0004 NEW)
|
||||
|
||||
add_library(foo SHARED empty.cpp)
|
||||
add_library(bar SHARED empty.cpp)
|
||||
add_library(bat SHARED empty.cpp)
|
||||
|
||||
# The negation here avoids the error.
|
||||
target_link_libraries(foo "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
|
||||
|
||||
# The below line causes the error.
|
||||
target_link_libraries(foo "$<$<TARGET_POLICY:CMP0004>: bat >")
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,5 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(CMP0004-OLD)
|
||||
run_cmake(CMP0004-NEW)
|
||||
run_cmake(CMP0004-policy-genex)
|
|
@ -60,6 +60,7 @@ add_RunCMake_test(find_package)
|
|||
add_RunCMake_test(include)
|
||||
add_RunCMake_test(include_directories)
|
||||
add_RunCMake_test(list)
|
||||
add_RunCMake_test(CMP0004)
|
||||
|
||||
if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
|
||||
add_RunCMake_test(include_external_msproject)
|
||||
|
|
Loading…
Reference in New Issue