Merge branch 'master' into sublime-text-2-generator
This commit is contained in:
commit
674bd6e778
|
@ -9,6 +9,8 @@
|
|||
# configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
|
||||
# file for installing a project or library. It helps making the resulting package
|
||||
# relocatable by avoiding hardcoded paths in the installed Config.cmake file.
|
||||
# <Name>Config.cmake files installed under UNIX into /lib(64) or /usr/lib(64) are
|
||||
# considered system packages and are not relocatable.
|
||||
#
|
||||
# In a FooConfig.cmake file there may be code like this to make the
|
||||
# install destinations know to the using project:
|
||||
|
@ -173,17 +175,33 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
|
|||
else()
|
||||
set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
|
||||
endif()
|
||||
|
||||
# with the /usr-move, /lib(64) is a symlink to /usr/lib on Fedora, ArchLinux, Mageira and others.
|
||||
# If we are installed to such a location, force using absolute paths.
|
||||
set(forceAbsolutePaths FALSE)
|
||||
if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
|
||||
set(forceAbsolutePaths TRUE)
|
||||
endif()
|
||||
|
||||
file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
|
||||
|
||||
foreach(var ${CCF_PATH_VARS})
|
||||
if(NOT DEFINED ${var})
|
||||
message(FATAL_ERROR "Variable ${var} does not exist")
|
||||
else()
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
|
||||
PACKAGE_${var} "${${var}}")
|
||||
if(forceAbsolutePaths)
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
set(PACKAGE_${var} "${${var}}")
|
||||
else()
|
||||
set(PACKAGE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
|
||||
endif()
|
||||
else()
|
||||
set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
|
||||
PACKAGE_${var} "${${var}}")
|
||||
else()
|
||||
set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
|
|
@ -1558,8 +1558,11 @@ function(_ep_add_configure_command name)
|
|||
set(file_deps)
|
||||
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
|
||||
foreach(dep IN LISTS deps)
|
||||
_ep_get_step_stampfile(${dep} "done" done_stamp_file)
|
||||
list(APPEND file_deps ${done_stamp_file})
|
||||
get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
|
||||
if(is_ep)
|
||||
_ep_get_step_stampfile(${dep} "done" done_stamp_file)
|
||||
list(APPEND file_deps ${done_stamp_file})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
set(CMake_VERSION_MAJOR 2)
|
||||
set(CMake_VERSION_MINOR 8)
|
||||
set(CMake_VERSION_PATCH 10)
|
||||
set(CMake_VERSION_TWEAK 20130110)
|
||||
set(CMake_VERSION_TWEAK 20130129)
|
||||
#set(CMake_VERSION_RC 1)
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"target in the same buildsystem. Expands to the empty string " \
|
||||
"otherwise.\n" \
|
||||
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
|
||||
" $<TARGET_DEFINED:tgt> = '1' if tgt is a target, else '0'\n" \
|
||||
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
|
||||
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
|
||||
"where \"tgt\" is the name of a target. " \
|
||||
|
@ -46,9 +47,14 @@
|
|||
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \
|
||||
"\n" \
|
||||
" $<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_PROPERTY:tgt,prop> = The value of the property prop " \
|
||||
"on the target tgt.\n" \
|
||||
"Note that tgt is not added as a dependency of 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" \
|
||||
|
@ -59,7 +65,7 @@
|
|||
#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \
|
||||
CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
|
||||
"Expressions with an implicit 'this' target:\n" \
|
||||
" $<TARGET_PROPERTY:prop> = The value of the property prop on\n" \
|
||||
" $<TARGET_PROPERTY:prop> = The value of the property prop on " \
|
||||
"the target on which the generator expression is evaluated.\n" \
|
||||
""
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
cmTarget* te = *tei;
|
||||
this->GenerateImportTargetCode(os, te);
|
||||
|
||||
te->AppendBuildInterfaceIncludes();
|
||||
|
||||
ImportPropertyMap properties;
|
||||
|
||||
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
|
||||
|
@ -70,20 +72,23 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||
te, properties);
|
||||
this->PopulateCompatibleInterfaceProperties(te, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(te, os, properties);
|
||||
}
|
||||
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
|
||||
// Generate import file content for each configuration.
|
||||
for(std::vector<std::string>::const_iterator
|
||||
ci = this->Configurations.begin();
|
||||
ci != this->Configurations.end(); ++ci)
|
||||
{
|
||||
this->GenerateImportConfig(os, ci->c_str());
|
||||
this->GenerateImportConfig(os, ci->c_str(), missingTargets);
|
||||
}
|
||||
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -91,7 +96,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
void
|
||||
cmExportBuildFileGenerator
|
||||
::GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config, std::string const& suffix)
|
||||
const char* config, std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
tei = this->Exports->begin();
|
||||
|
@ -104,9 +110,12 @@ cmExportBuildFileGenerator
|
|||
if(!properties.empty())
|
||||
{
|
||||
// Get the rest of the target details.
|
||||
std::vector<std::string> missingTargets;
|
||||
this->SetImportDetailProperties(config, suffix,
|
||||
target, properties, missingTargets);
|
||||
this->SetImportLinkInterface(config, suffix,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
target, properties, missingTargets);
|
||||
|
||||
|
||||
// TOOD: PUBLIC_HEADER_LOCATION
|
||||
// This should wait until the build feature propagation stuff
|
||||
|
@ -115,7 +124,6 @@ cmExportBuildFileGenerator
|
|||
// properties);
|
||||
|
||||
// Generate code in the export file.
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
this->GenerateImportPropertyCode(os, config, target, properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ protected:
|
|||
virtual bool GenerateMainFile(std::ostream& os);
|
||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config,
|
||||
std::string const& suffix);
|
||||
std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets);
|
||||
virtual void HandleMissingTarget(std::string& link_libs,
|
||||
std::vector<std::string>& missingTargets,
|
||||
cmMakefile* mf,
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "cmTarget.h"
|
||||
#include "cmTargetExport.h"
|
||||
#include "cmVersion.h"
|
||||
#include "cmComputeLinkInformation.h"
|
||||
|
||||
#include <cmsys/auto_ptr.hxx>
|
||||
|
||||
|
@ -81,16 +82,16 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
|
||||
// Protect that file against use with older CMake versions.
|
||||
os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
|
||||
os << "IF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
|
||||
<< " MESSAGE(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
|
||||
<< "ENDIF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n";
|
||||
os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
|
||||
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
|
||||
<< "endif()\n";
|
||||
|
||||
// Isolate the file policy level.
|
||||
// We use 2.6 here instead of the current version because newer
|
||||
// versions of CMake should be able to export files imported by 2.6
|
||||
// until the import format changes.
|
||||
os << "CMAKE_POLICY(PUSH)\n"
|
||||
<< "CMAKE_POLICY(VERSION 2.6)\n";
|
||||
os << "cmake_policy(PUSH)\n"
|
||||
<< "cmake_policy(VERSION 2.6)\n";
|
||||
|
||||
// Start with the import file header.
|
||||
this->GenerateImportHeaderCode(os);
|
||||
|
@ -100,14 +101,15 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
|
||||
// End with the import file footer.
|
||||
this->GenerateImportFooterCode(os);
|
||||
os << "CMAKE_POLICY(POP)\n";
|
||||
os << "cmake_policy(POP)\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
||||
const char* config)
|
||||
const char* config,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
// Construct the property configuration suffix.
|
||||
std::string suffix = "_";
|
||||
|
@ -121,7 +123,19 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
|||
}
|
||||
|
||||
// Generate the per-config target information.
|
||||
this->GenerateImportTargetsConfig(os, config, suffix);
|
||||
this->GenerateImportTargetsConfig(os, config, suffix, missingTargets);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
||||
cmTarget *target,
|
||||
ImportPropertyMap &properties)
|
||||
{
|
||||
const char *input = target->GetProperty(propName);
|
||||
if (input)
|
||||
{
|
||||
properties[propName] = input;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -164,6 +178,85 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
|||
properties, missingTargets);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void getPropertyContents(cmTarget *tgt, const char *prop,
|
||||
std::set<std::string> &ifaceProperties)
|
||||
{
|
||||
const char *p = tgt->GetProperty(prop);
|
||||
if (!p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> content;
|
||||
cmSystemTools::ExpandListArgument(p, content);
|
||||
for (std::vector<std::string>::const_iterator ci = content.begin();
|
||||
ci != content.end(); ++ci)
|
||||
{
|
||||
ifaceProperties.insert(*ci);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void getCompatibleInterfaceProperties(cmTarget *target,
|
||||
std::set<std::string> &ifaceProperties,
|
||||
const char *config)
|
||||
{
|
||||
cmComputeLinkInformation *info = target->GetLinkInformation(config);
|
||||
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
getPropertyContents(li->Target,
|
||||
"COMPATIBLE_INTERFACE_BOOL",
|
||||
ifaceProperties);
|
||||
getPropertyContents(li->Target,
|
||||
"COMPATIBLE_INTERFACE_STRING",
|
||||
ifaceProperties);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
|
||||
cmTarget *target,
|
||||
ImportPropertyMap &properties)
|
||||
{
|
||||
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
|
||||
target, properties);
|
||||
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
|
||||
target, properties);
|
||||
|
||||
std::set<std::string> ifaceProperties;
|
||||
|
||||
getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
|
||||
getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
|
||||
|
||||
getCompatibleInterfaceProperties(target, ifaceProperties, 0);
|
||||
|
||||
std::vector<std::string> configNames;
|
||||
target->GetMakefile()->GetConfigurations(configNames);
|
||||
|
||||
for (std::vector<std::string>::const_iterator ci = configNames.begin();
|
||||
ci != configNames.end(); ++ci)
|
||||
{
|
||||
getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str());
|
||||
}
|
||||
|
||||
for (std::set<std::string>::const_iterator it = ifaceProperties.begin();
|
||||
it != ifaceProperties.end(); ++it)
|
||||
{
|
||||
this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(),
|
||||
target, properties);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
|
||||
std::ostream& os,
|
||||
|
@ -173,7 +266,7 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
|
|||
{
|
||||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetName();
|
||||
os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
|
||||
os << "set_target_properties(" << targetName << " PROPERTIES\n";
|
||||
for(ImportPropertyMap::const_iterator pi = properties.begin();
|
||||
pi != properties.end(); ++pi)
|
||||
{
|
||||
|
@ -183,9 +276,89 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmExportFileGenerator::AddTargetNamespace(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
cmMakefile *mf = target->GetMakefile();
|
||||
|
||||
cmTarget *tgt = mf->FindTargetToUse(input.c_str());
|
||||
if (!tgt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
input = this->Namespace + input;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string namespacedTarget;
|
||||
this->HandleMissingTarget(namespacedTarget, missingTargets,
|
||||
mf, target, tgt);
|
||||
if (!namespacedTarget.empty())
|
||||
{
|
||||
input = namespacedTarget;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool isGeneratorExpression(const std::string &lib)
|
||||
{
|
||||
const std::string::size_type openpos = lib.find("$<");
|
||||
return (openpos != std::string::npos)
|
||||
&& (lib.find(">", openpos) != std::string::npos);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets,
|
||||
FreeTargetsReplace replace)
|
||||
{
|
||||
if (replace == NoReplaceFreeTargets)
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> parts;
|
||||
cmGeneratorExpression::Split(input, parts);
|
||||
|
||||
std::string sep;
|
||||
input = "";
|
||||
for(std::vector<std::string>::iterator li = parts.begin();
|
||||
li != parts.end(); ++li)
|
||||
{
|
||||
if (!isGeneratorExpression(*li))
|
||||
{
|
||||
this->AddTargetNamespace(*li, target, missingTargets);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpression(
|
||||
*li,
|
||||
target,
|
||||
missingTargets);
|
||||
}
|
||||
input += sep + *li;
|
||||
sep = ";";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets)
|
||||
|
@ -212,45 +385,17 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
|||
continue;
|
||||
}
|
||||
|
||||
const std::string targetName = input.substr(nameStartPos,
|
||||
std::string targetName = input.substr(nameStartPos,
|
||||
commaPos - nameStartPos);
|
||||
|
||||
pos = nameStartPos; // We're not going to replace the entire expression,
|
||||
// but only the target parameter.
|
||||
if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
|
||||
{
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
pos += targetName.size();
|
||||
}
|
||||
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
input.replace(pos, targetName.size(),
|
||||
this->Namespace + targetName);
|
||||
pos += this->Namespace.size() + targetName.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string namespacedTarget;
|
||||
this->HandleMissingTarget(namespacedTarget, missingTargets,
|
||||
mf, target, tgt);
|
||||
if (!namespacedTarget.empty())
|
||||
{
|
||||
input.replace(pos, targetName.size(), namespacedTarget);
|
||||
pos += namespacedTarget.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
{
|
||||
errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
|
||||
"its first parameter to be a reachable target.";
|
||||
}
|
||||
lastPos = pos;
|
||||
if (!errorString.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
input.replace(nameStartPos, commaPos - nameStartPos, targetName);
|
||||
lastPos = pos + targetName.size();
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
|
@ -267,51 +412,24 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
|||
if (endPos == input.npos)
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> expression incomplete";
|
||||
break;
|
||||
}
|
||||
const std::string targetName = input.substr(nameStartPos,
|
||||
std::string targetName = input.substr(nameStartPos,
|
||||
endPos - nameStartPos);
|
||||
if(targetName.find("$<", lastPos) != input.npos)
|
||||
if(targetName.find("$<") != input.npos)
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
|
||||
"literal.";
|
||||
break;
|
||||
}
|
||||
if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
|
||||
{
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
|
||||
targetName);
|
||||
pos += sizeof("$<TARGET_NAME:") + targetName.size();
|
||||
}
|
||||
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
|
||||
this->Namespace + targetName);
|
||||
pos += sizeof("$<TARGET_NAME:") + targetName.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string namespacedTarget;
|
||||
this->HandleMissingTarget(namespacedTarget, missingTargets,
|
||||
mf, target, tgt);
|
||||
if (!namespacedTarget.empty())
|
||||
{
|
||||
input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
|
||||
namespacedTarget);
|
||||
pos += sizeof("$<TARGET_NAME:") + targetName.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
|
||||
"reachable target.";
|
||||
}
|
||||
lastPos = pos;
|
||||
if (!errorString.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
input.replace(pos, endPos - pos + 1, targetName);
|
||||
lastPos = endPos;
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
|
@ -319,6 +437,64 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator
|
||||
::SetImportLinkInterface(const char* config, std::string const& suffix,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
cmTarget* target, ImportPropertyMap& properties,
|
||||
std::vector<std::string>& missingTargets)
|
||||
{
|
||||
// Add the transitive link dependencies for this configuration.
|
||||
cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
|
||||
target);
|
||||
if (!iface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (iface->ImplementationIsInterface)
|
||||
{
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES",
|
||||
iface->Libraries, properties, missingTargets);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *propContent;
|
||||
|
||||
if (const char *prop_suffixed = target->GetProperty(
|
||||
("LINK_INTERFACE_LIBRARIES" + suffix).c_str()))
|
||||
{
|
||||
propContent = prop_suffixed;
|
||||
}
|
||||
else if (const char *prop = target->GetProperty(
|
||||
"LINK_INTERFACE_LIBRARIES"))
|
||||
{
|
||||
propContent = prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*propContent)
|
||||
{
|
||||
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = "";
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prepro = cmGeneratorExpression::Preprocess(propContent,
|
||||
preprocessRule);
|
||||
if (!prepro.empty())
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target,
|
||||
missingTargets,
|
||||
ReplaceFreeTargets);
|
||||
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator
|
||||
|
@ -363,9 +539,7 @@ cmExportFileGenerator
|
|||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_INTERFACE_LANGUAGES",
|
||||
iface->Languages, properties, missingTargets);
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES",
|
||||
iface->Libraries, properties, missingTargets);
|
||||
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_DEPENDENT_LIBRARIES",
|
||||
iface->SharedDeps, properties, missingTargets);
|
||||
|
@ -397,9 +571,6 @@ cmExportFileGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
// Get the makefile in which to lookup target information.
|
||||
cmMakefile* mf = target->GetMakefile();
|
||||
|
||||
// Construct the property value.
|
||||
std::string link_libs;
|
||||
const char* sep = "";
|
||||
|
@ -410,33 +581,9 @@ cmExportFileGenerator
|
|||
link_libs += sep;
|
||||
sep = ";";
|
||||
|
||||
// Append this entry.
|
||||
if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
|
||||
{
|
||||
// This is a target.
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
// The target is imported (and therefore is not in the
|
||||
// export). Append the raw name.
|
||||
link_libs += *li;
|
||||
}
|
||||
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
// The target is in the export. Append it with the export
|
||||
// namespace.
|
||||
link_libs += this->Namespace;
|
||||
link_libs += *li;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append the raw name.
|
||||
link_libs += *li;
|
||||
}
|
||||
std::string temp = *li;
|
||||
this->AddTargetNamespace(temp, target, missingTargets);
|
||||
link_libs += temp;
|
||||
}
|
||||
|
||||
// Store the property.
|
||||
|
@ -469,7 +616,7 @@ void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
|
|||
void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
|
||||
{
|
||||
os << "# Commands beyond this point should not need to know the version.\n"
|
||||
<< "SET(CMAKE_IMPORT_FILE_VERSION)\n";
|
||||
<< "set(CMAKE_IMPORT_FILE_VERSION)\n";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -478,7 +625,7 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
|
|||
// Store an import file format version. This will let us change the
|
||||
// format later while still allowing old import files to work.
|
||||
os << "# Commands may need to know the format version.\n"
|
||||
<< "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
|
||||
<< "set(CMAKE_IMPORT_FILE_VERSION 1)\n"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
|
@ -486,31 +633,31 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
|
|||
void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os,
|
||||
const std::string &expectedTargets)
|
||||
{
|
||||
os << "SET(_targetsDefined)\n"
|
||||
"SET(_targetsNotDefined)\n"
|
||||
"SET(_expectedTargets)\n"
|
||||
"FOREACH(_expectedTarget " << expectedTargets << ")\n"
|
||||
" LIST(APPEND _expectedTargets ${_expectedTarget})\n"
|
||||
" IF(NOT TARGET ${_expectedTarget})\n"
|
||||
" LIST(APPEND _targetsNotDefined ${_expectedTarget})\n"
|
||||
" ENDIF(NOT TARGET ${_expectedTarget})\n"
|
||||
" IF(TARGET ${_expectedTarget})\n"
|
||||
" LIST(APPEND _targetsDefined ${_expectedTarget})\n"
|
||||
" ENDIF(TARGET ${_expectedTarget})\n"
|
||||
"ENDFOREACH(_expectedTarget)\n"
|
||||
"IF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
|
||||
" SET(CMAKE_IMPORT_FILE_VERSION)\n"
|
||||
" CMAKE_POLICY(POP)\n"
|
||||
" RETURN()\n"
|
||||
"ENDIF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
|
||||
"IF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
|
||||
" MESSAGE(FATAL_ERROR \"Some (but not all) targets in this export "
|
||||
os << "set(_targetsDefined)\n"
|
||||
"set(_targetsNotDefined)\n"
|
||||
"set(_expectedTargets)\n"
|
||||
"foreach(_expectedTarget " << expectedTargets << ")\n"
|
||||
" list(APPEND _expectedTargets ${_expectedTarget})\n"
|
||||
" if(NOT TARGET ${_expectedTarget})\n"
|
||||
" list(APPEND _targetsNotDefined ${_expectedTarget})\n"
|
||||
" endif()\n"
|
||||
" if(TARGET ${_expectedTarget})\n"
|
||||
" list(APPEND _targetsDefined ${_expectedTarget})\n"
|
||||
" endif()\n"
|
||||
"endforeach()\n"
|
||||
"if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
|
||||
" set(CMAKE_IMPORT_FILE_VERSION)\n"
|
||||
" cmake_policy(POP)\n"
|
||||
" return()\n"
|
||||
"endif()\n"
|
||||
"if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
|
||||
" message(FATAL_ERROR \"Some (but not all) targets in this export "
|
||||
"set were already defined.\\nTargets Defined: ${_targetsDefined}\\n"
|
||||
"Targets not yet defined: ${_targetsNotDefined}\\n\")\n"
|
||||
"ENDIF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
|
||||
"UNSET(_targetsDefined)\n"
|
||||
"UNSET(_targetsNotDefined)\n"
|
||||
"UNSET(_expectedTargets)\n"
|
||||
"endif()\n"
|
||||
"unset(_targetsDefined)\n"
|
||||
"unset(_targetsNotDefined)\n"
|
||||
"unset(_expectedTargets)\n"
|
||||
"\n\n";
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -527,16 +674,16 @@ cmExportFileGenerator
|
|||
switch(target->GetType())
|
||||
{
|
||||
case cmTarget::EXECUTABLE:
|
||||
os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
|
||||
os << "add_executable(" << targetName << " IMPORTED)\n";
|
||||
break;
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
|
||||
os << "add_library(" << targetName << " STATIC IMPORTED)\n";
|
||||
break;
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
|
||||
os << "add_library(" << targetName << " SHARED IMPORTED)\n";
|
||||
break;
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
|
||||
os << "add_library(" << targetName << " MODULE IMPORTED)\n";
|
||||
break;
|
||||
default: // should never happen
|
||||
break;
|
||||
|
@ -545,27 +692,27 @@ cmExportFileGenerator
|
|||
// Mark the imported executable if it has exports.
|
||||
if(target->IsExecutableWithExports())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY ENABLE_EXPORTS 1)\n";
|
||||
}
|
||||
|
||||
// Mark the imported library if it is a framework.
|
||||
if(target->IsFrameworkOnApple())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY FRAMEWORK 1)\n";
|
||||
}
|
||||
|
||||
// Mark the imported executable if it is an application bundle.
|
||||
if(target->IsAppBundleOnApple())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY MACOSX_BUNDLE 1)\n";
|
||||
}
|
||||
|
||||
if (target->IsCFBundleOnApple())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY BUNDLE 1)\n";
|
||||
}
|
||||
os << "\n";
|
||||
|
@ -585,7 +732,7 @@ cmExportFileGenerator
|
|||
// Set the import properties.
|
||||
os << "# Import target \"" << targetName << "\" for configuration \""
|
||||
<< config << "\"\n";
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
|
||||
if(config && *config)
|
||||
{
|
||||
|
@ -596,7 +743,7 @@ cmExportFileGenerator
|
|||
os << "NOCONFIG";
|
||||
}
|
||||
os << ")\n";
|
||||
os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
|
||||
os << "set_target_properties(" << targetName << " PROPERTIES\n";
|
||||
for(ImportPropertyMap::const_iterator pi = properties.begin();
|
||||
pi != properties.end(); ++pi)
|
||||
{
|
||||
|
@ -611,21 +758,29 @@ cmExportFileGenerator
|
|||
void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
|
||||
const std::vector<std::string>& missingTargets)
|
||||
{
|
||||
if (missingTargets.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
os << "# Make sure the targets which have been exported in some other \n"
|
||||
"# export set exist.\n";
|
||||
std::set<std::string> emitted;
|
||||
for(unsigned int i=0; i<missingTargets.size(); ++i)
|
||||
{
|
||||
os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
|
||||
<< " IF(CMAKE_FIND_PACKAGE_NAME)\n"
|
||||
<< " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
|
||||
<< " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
|
||||
<< "\"Required imported target \\\"" << missingTargets[i]
|
||||
<< "\\\" not found ! \")\n"
|
||||
<< " ELSE()\n"
|
||||
<< " MESSAGE(FATAL_ERROR \"Required imported target \\\""
|
||||
<< missingTargets[i] << "\\\" not found ! \")\n"
|
||||
<< " ENDIF()\n"
|
||||
<< "ENDIF()\n";
|
||||
if (emitted.insert(missingTargets[i]).second)
|
||||
{
|
||||
os << "if(NOT TARGET \"" << missingTargets[i] << "\" )\n"
|
||||
<< " if(CMAKE_FIND_PACKAGE_NAME)\n"
|
||||
<< " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
|
||||
<< " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
|
||||
<< "\"Required imported target \\\"" << missingTargets[i]
|
||||
<< "\\\" not found ! \")\n"
|
||||
<< " else()\n"
|
||||
<< " message(FATAL_ERROR \"Required imported target \\\""
|
||||
<< missingTargets[i] << "\\\" not found ! \")\n"
|
||||
<< " endif()\n"
|
||||
<< "endif()\n";
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
|
@ -643,10 +798,10 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
|
|||
// on SUSE with a mysql pkg-config file, which claimed everything is fine,
|
||||
// but the development package was not installed.).
|
||||
os << "# Loop over all imported files and verify that they actually exist\n"
|
||||
"FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n"
|
||||
" FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
|
||||
" IF(NOT EXISTS \"${file}\" )\n"
|
||||
" MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\""
|
||||
"foreach(target ${_IMPORT_CHECK_TARGETS} )\n"
|
||||
" foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
|
||||
" if(NOT EXISTS \"${file}\" )\n"
|
||||
" message(FATAL_ERROR \"The imported target \\\"${target}\\\""
|
||||
" references the file\n"
|
||||
" \\\"${file}\\\"\n"
|
||||
"but this file does not exist. Possible reasons include:\n"
|
||||
|
@ -656,11 +811,11 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
|
|||
" \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
|
||||
"but not all the files it references.\n"
|
||||
"\")\n"
|
||||
" ENDIF()\n"
|
||||
" ENDFOREACH()\n"
|
||||
" UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n"
|
||||
"ENDFOREACH()\n"
|
||||
"UNSET(_IMPORT_CHECK_TARGETS)\n"
|
||||
" endif()\n"
|
||||
" endforeach()\n"
|
||||
" unset(_IMPORT_CHECK_FILES_FOR_${target})\n"
|
||||
"endforeach()\n"
|
||||
"unset(_IMPORT_CHECK_TARGETS)\n"
|
||||
"\n";
|
||||
}
|
||||
|
||||
|
@ -676,8 +831,8 @@ cmExportFileGenerator
|
|||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetName();
|
||||
|
||||
os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
|
||||
"LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
|
||||
os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
|
||||
"list(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
|
||||
|
||||
for(std::set<std::string>::const_iterator li = importedLocations.begin();
|
||||
li != importedLocations.end();
|
||||
|
|
|
@ -47,7 +47,8 @@ protected:
|
|||
|
||||
// Generate per-configuration target information to the given output
|
||||
// stream.
|
||||
void GenerateImportConfig(std::ostream& os, const char* config);
|
||||
void GenerateImportConfig(std::ostream& os, const char* config,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
// Methods to implement export file code generation.
|
||||
void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
|
||||
|
@ -85,7 +86,8 @@ protected:
|
|||
/** Each subclass knows where the target files are located. */
|
||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config,
|
||||
std::string const& suffix) = 0;
|
||||
std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets) = 0;
|
||||
|
||||
/** Each subclass knows how to deal with a target that is missing from an
|
||||
* export set. */
|
||||
|
@ -99,12 +101,27 @@ protected:
|
|||
cmGeneratorExpression::PreprocessContext,
|
||||
ImportPropertyMap &properties,
|
||||
std::vector<std::string> &missingTargets);
|
||||
void PopulateInterfaceProperty(const char *propName, cmTarget *target,
|
||||
ImportPropertyMap &properties);
|
||||
void PopulateCompatibleInterfaceProperties(cmTarget *target,
|
||||
ImportPropertyMap &properties);
|
||||
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
||||
const ImportPropertyMap &properties);
|
||||
|
||||
void SetImportLinkInterface(const char* config, std::string const& suffix,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
cmTarget* target, ImportPropertyMap& properties,
|
||||
std::vector<std::string>& missingTargets);
|
||||
|
||||
enum FreeTargetsReplace {
|
||||
ReplaceFreeTargets,
|
||||
NoReplaceFreeTargets
|
||||
};
|
||||
|
||||
void ResolveTargetsInGeneratorExpressions(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets);
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets,
|
||||
FreeTargetsReplace replace = NoReplaceFreeTargets);
|
||||
|
||||
// The namespace in which the exports are placed in the generated file.
|
||||
std::string Namespace;
|
||||
|
@ -128,6 +145,13 @@ private:
|
|||
cmGeneratorExpression::PreprocessContext,
|
||||
ImportPropertyMap &properties,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
bool AddTargetNamespace(std::string &input, cmTarget* target,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
void ResolveTargetsInGeneratorExpression(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \""
|
||||
e << "install(EXPORT \""
|
||||
<< this->IEGen->GetExportSet()->GetName()
|
||||
<< "\" ...) " << "includes target \"" << te->Target->GetName()
|
||||
<< "\" more than once in the export set.";
|
||||
|
@ -89,39 +89,47 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
te,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||
te, properties);
|
||||
this->PopulateCompatibleInterfaceProperties(te, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(te, os, properties);
|
||||
}
|
||||
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
|
||||
// Now load per-configuration properties for them.
|
||||
os << "# Load information for each installed configuration.\n"
|
||||
<< "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||
<< "FILE(GLOB CONFIG_FILES \"${_DIR}/"
|
||||
<< "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||
<< "file(GLOB CONFIG_FILES \"${_DIR}/"
|
||||
<< this->GetConfigImportFileGlob() << "\")\n"
|
||||
<< "FOREACH(f ${CONFIG_FILES})\n"
|
||||
<< " INCLUDE(${f})\n"
|
||||
<< "ENDFOREACH(f)\n"
|
||||
<< "foreach(f ${CONFIG_FILES})\n"
|
||||
<< " include(${f})\n"
|
||||
<< "endforeach()\n"
|
||||
<< "\n";
|
||||
|
||||
this->GenerateImportedFileCheckLoop(os);
|
||||
|
||||
// Generate an import file for each configuration.
|
||||
bool result = true;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
ci = this->Configurations.begin();
|
||||
ci != this->Configurations.end(); ++ci)
|
||||
{
|
||||
if(!this->GenerateImportFileConfig(ci->c_str()))
|
||||
if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
||||
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
// Skip configurations not enabled for this export.
|
||||
if(!this->IEGen->InstallsForConfig(config))
|
||||
|
@ -161,7 +169,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
|||
this->GenerateImportHeaderCode(os, config);
|
||||
|
||||
// Generate the per-config target information.
|
||||
this->GenerateImportConfig(os, config);
|
||||
this->GenerateImportConfig(os, config, missingTargets);
|
||||
|
||||
// End with the import file footer.
|
||||
this->GenerateImportFooterCode(os);
|
||||
|
@ -176,7 +184,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
|||
void
|
||||
cmExportInstallFileGenerator
|
||||
::GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config, std::string const& suffix)
|
||||
const char* config, std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
// Add code to compute the installation prefix relative to the
|
||||
// import file location.
|
||||
|
@ -185,12 +194,12 @@ cmExportInstallFileGenerator
|
|||
{
|
||||
std::string dest = installDest;
|
||||
os << "# Compute the installation prefix relative to this file.\n"
|
||||
<< "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
|
||||
<< "get_filename_component(_IMPORT_PREFIX "
|
||||
<< "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
||||
while(!dest.empty())
|
||||
{
|
||||
os <<
|
||||
"GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
|
||||
"get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
|
||||
dest = cmSystemTools::GetFilenamePath(dest);
|
||||
}
|
||||
os << "\n";
|
||||
|
@ -225,10 +234,13 @@ cmExportInstallFileGenerator
|
|||
if(!properties.empty())
|
||||
{
|
||||
// Get the rest of the target details.
|
||||
std::vector<std::string> missingTargets;
|
||||
this->SetImportDetailProperties(config, suffix,
|
||||
te->Target, properties, missingTargets);
|
||||
|
||||
this->SetImportLinkInterface(config, suffix,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
te->Target, properties, missingTargets);
|
||||
|
||||
// TOOD: PUBLIC_HEADER_LOCATION
|
||||
// This should wait until the build feature propagation stuff
|
||||
// is done. Then this can be a propagated include directory.
|
||||
|
@ -236,20 +248,17 @@ cmExportInstallFileGenerator
|
|||
// properties);
|
||||
|
||||
// Generate code in the export file.
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
this->GenerateImportPropertyCode(os, config, te->Target, properties);
|
||||
this->GenerateImportedFileChecksCode(os, te->Target, properties,
|
||||
importedLocations);
|
||||
}
|
||||
}
|
||||
|
||||
this->GenerateImportedFileCheckLoop(os);
|
||||
|
||||
// Cleanup the import prefix variable.
|
||||
if(!this->ImportPrefix.empty())
|
||||
{
|
||||
os << "# Cleanup temporary variables.\n"
|
||||
<< "SET(_IMPORT_PREFIX)\n"
|
||||
<< "set(_IMPORT_PREFIX)\n"
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +428,7 @@ cmExportInstallFileGenerator
|
|||
{
|
||||
const char* installDest = this->IEGen->GetDestination();
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \""
|
||||
e << "install(EXPORT \""
|
||||
<< this->IEGen->GetExportSet()->GetName()
|
||||
<< "\") given absolute "
|
||||
<< "DESTINATION \"" << installDest << "\" but the export "
|
||||
|
@ -437,7 +446,7 @@ cmExportInstallFileGenerator
|
|||
int occurrences)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \""
|
||||
e << "install(EXPORT \""
|
||||
<< this->IEGen->GetExportSet()->GetName()
|
||||
<< "\" ...) "
|
||||
<< "includes target \"" << depender->GetName()
|
||||
|
|
|
@ -56,7 +56,8 @@ protected:
|
|||
virtual bool GenerateMainFile(std::ostream& os);
|
||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config,
|
||||
std::string const& suffix);
|
||||
std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets);
|
||||
virtual void HandleMissingTarget(std::string& link_libs,
|
||||
std::vector<std::string>& missingTargets,
|
||||
cmMakefile* mf,
|
||||
|
@ -72,7 +73,8 @@ protected:
|
|||
|
||||
|
||||
/** Generate a per-configuration file for the targets. */
|
||||
bool GenerateImportFileConfig(const char* config);
|
||||
bool GenerateImportFileConfig(const char* config,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
/** Fill in properties indicating installed file locations. */
|
||||
void SetImportLocationProperty(const char* config,
|
||||
|
|
|
@ -621,7 +621,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
|
|||
->GetGeneratorTarget(target);
|
||||
|
||||
// the compilerdefines for this target
|
||||
std::string cdefs = gtgt->GetCompileDefinitions();
|
||||
std::string cdefs = target->GetCompileDefinitions();
|
||||
|
||||
if(!cdefs.empty())
|
||||
{
|
||||
|
|
|
@ -37,9 +37,13 @@ bool cmFLTKWrapUICommand
|
|||
// get the list of GUI files from which .cxx and .h will be generated
|
||||
std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory();
|
||||
|
||||
{
|
||||
// Some of the generated files are *.h so the directory "GUI"
|
||||
// where they are created have to be added to the include path
|
||||
this->Makefile->AddIncludeDirectory( outputDirectory.c_str() );
|
||||
std::vector<std::string> outputDirectories;
|
||||
outputDirectories.push_back(outputDirectory);
|
||||
this->Makefile->AddIncludeDirectories( outputDirectories );
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::iterator i = (newArgs.begin() + 1);
|
||||
i != newArgs.end(); i++)
|
||||
|
|
|
@ -147,6 +147,38 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string stripEmptyListElements(const std::string &input)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
const char *c = input.c_str();
|
||||
bool skipSemiColons = true;
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
if(c[0] == ';')
|
||||
{
|
||||
if(skipSemiColons)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
skipSemiColons = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
skipSemiColons = false;
|
||||
}
|
||||
result += *c;
|
||||
}
|
||||
|
||||
if (!result.empty() && *(result.end() - 1) == ';')
|
||||
{
|
||||
result.resize(result.size() - 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string stripAllGeneratorExpressions(const std::string &input)
|
||||
{
|
||||
|
@ -186,7 +218,7 @@ static std::string stripAllGeneratorExpressions(const std::string &input)
|
|||
lastPos = pos;
|
||||
}
|
||||
result += input.substr(lastPos);
|
||||
return result;
|
||||
return stripEmptyListElements(result);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -247,7 +279,68 @@ static std::string stripExportInterface(const std::string &input,
|
|||
}
|
||||
result += input.substr(lastPos);
|
||||
|
||||
return result;
|
||||
return stripEmptyListElements(result);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorExpression::Split(const std::string &input,
|
||||
std::vector<std::string> &output)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
while((pos = input.find("$<", lastPos)) != input.npos)
|
||||
{
|
||||
std::string part = input.substr(lastPos, pos - lastPos);
|
||||
std::string preGenex;
|
||||
if (!part.empty())
|
||||
{
|
||||
std::string::size_type startPos = input.rfind(";", pos);
|
||||
if (startPos != pos - 1 && startPos >= lastPos)
|
||||
{
|
||||
part = input.substr(lastPos, startPos - lastPos);
|
||||
preGenex = input.substr(startPos + 1, pos - startPos - 1);
|
||||
}
|
||||
cmSystemTools::ExpandListArgument(part.c_str(), output);
|
||||
}
|
||||
pos += 2;
|
||||
int nestingLevel = 1;
|
||||
const char *c = input.c_str() + pos;
|
||||
const char * const cStart = c;
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
if(c[0] == '$' && c[1] == '<')
|
||||
{
|
||||
++nestingLevel;
|
||||
++c;
|
||||
continue;
|
||||
}
|
||||
if(c[0] == '>')
|
||||
{
|
||||
--nestingLevel;
|
||||
if (nestingLevel == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
// Capture the part after the genex and before the next ';'
|
||||
if(c[0] == ';')
|
||||
{
|
||||
--c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const std::string::size_type traversed = (c - cStart) + 1;
|
||||
output.push_back(preGenex + "$<" + input.substr(pos, traversed));
|
||||
pos += traversed;
|
||||
lastPos = pos;
|
||||
}
|
||||
if (lastPos < input.size())
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(input.substr(lastPos), output);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -59,6 +59,9 @@ public:
|
|||
static std::string Preprocess(const std::string &input,
|
||||
PreprocessContext context);
|
||||
|
||||
static void Split(const std::string &input,
|
||||
std::vector<std::string> &output);
|
||||
|
||||
private:
|
||||
cmGeneratorExpression(const cmGeneratorExpression &);
|
||||
void operator=(const cmGeneratorExpression &);
|
||||
|
|
|
@ -106,3 +106,22 @@ cmGeneratorExpressionDAGChecker::checkGraph() const
|
|||
}
|
||||
return DAG;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
|
||||
{
|
||||
const cmGeneratorExpressionDAGChecker *top = this;
|
||||
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||
while (parent)
|
||||
{
|
||||
top = parent;
|
||||
parent = parent->Parent;
|
||||
}
|
||||
|
||||
const char *prop = top->Property.c_str();
|
||||
return (strcmp(prop, "LINK_LIBRARIES") == 0
|
||||
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|
||||
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
|
||||
|| strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 26) == 0
|
||||
|| strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 35) == 0);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ struct cmGeneratorExpressionDAGChecker
|
|||
|
||||
void reportError(cmGeneratorExpressionContext *context,
|
||||
const std::string &expr);
|
||||
|
||||
bool EvaluatingLinkLibraries();
|
||||
|
||||
private:
|
||||
Result checkGraph() const;
|
||||
|
||||
|
|
|
@ -289,6 +289,22 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
|||
} configurationTestNode;
|
||||
|
||||
|
||||
static const struct TargetDefinedNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetDefinedNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return context->Makefile->FindTargetToUse(parameters.front().c_str())
|
||||
? "1" : "0";
|
||||
}
|
||||
} targetDefinedNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* targetPropertyTransitiveWhitelist[] = {
|
||||
"INTERFACE_INCLUDE_DIRECTORIES"
|
||||
|
@ -426,6 +442,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
const char *prop = target->GetProperty(propertyName.c_str());
|
||||
if (!prop)
|
||||
{
|
||||
if (target->IsImported())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
if (propertyName == "POSITION_INDEPENDENT_CODE")
|
||||
{
|
||||
return target->GetLinkInterfaceDependentBoolProperty(
|
||||
"POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
|
||||
}
|
||||
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
|
||||
context->Config))
|
||||
{
|
||||
return target->GetLinkInterfaceDependentBoolProperty(
|
||||
propertyName,
|
||||
context->Config) ? "1" : "0";
|
||||
}
|
||||
if (target->IsLinkInterfaceDependentStringProperty(propertyName,
|
||||
context->Config))
|
||||
{
|
||||
return target->GetLinkInterfaceDependentStringProperty(
|
||||
propertyName,
|
||||
context->Config);
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
@ -471,6 +515,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
|
||||
|
@ -698,10 +841,14 @@ 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")
|
||||
return &installInterfaceNode;
|
||||
else if (identifier == "TARGET_DEFINED")
|
||||
return &targetDefinedNode;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -254,32 +254,3 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
|
|||
{
|
||||
return this->Target->GetIncludeDirectories(config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
|
||||
{
|
||||
std::string defPropName = "COMPILE_DEFINITIONS";
|
||||
if (config)
|
||||
{
|
||||
defPropName += "_" + cmSystemTools::UpperCase(config);
|
||||
}
|
||||
|
||||
const char *prop = this->Target->GetProperty(defPropName.c_str());
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
defPropName, 0, 0);
|
||||
return ge.Parse(prop)->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this->Target,
|
||||
&dagChecker);
|
||||
}
|
||||
|
|
|
@ -68,8 +68,6 @@ public:
|
|||
/** Get the include directories for this target. */
|
||||
std::vector<std::string> GetIncludeDirectories(const char *config);
|
||||
|
||||
std::string GetCompileDefinitions(const char *config = 0);
|
||||
|
||||
private:
|
||||
void ClassifySources();
|
||||
void LookupObjectLibraries();
|
||||
|
|
|
@ -941,19 +941,7 @@ void cmGlobalGenerator::Generate()
|
|||
|
||||
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
|
||||
{
|
||||
if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
|
||||
{
|
||||
const char *binDir = mf->GetStartOutputDirectory();
|
||||
const char *srcDir = mf->GetStartDirectory();
|
||||
const std::string dirs = std::string(binDir ? binDir : "")
|
||||
+ std::string(binDir ? ";" : "")
|
||||
+ std::string(srcDir ? srcDir : "");
|
||||
if (!dirs.empty())
|
||||
{
|
||||
tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
||||
("$<BUILD_INTERFACE:" + dirs + ">").c_str());
|
||||
}
|
||||
}
|
||||
tit->second.AppendBuildInterfaceIncludes();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -992,6 +980,7 @@ void cmGlobalGenerator::Generate()
|
|||
// Generate project files
|
||||
for (i = 0; i < this->LocalGenerators.size(); ++i)
|
||||
{
|
||||
this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
|
||||
this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
|
||||
this->LocalGenerators[i]->Generate();
|
||||
this->LocalGenerators[i]->GenerateInstallRules();
|
||||
|
@ -1075,7 +1064,8 @@ void cmGlobalGenerator::CreateAutomocTargets()
|
|||
if(target.GetType() == cmTarget::EXECUTABLE ||
|
||||
target.GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
target.GetType() == cmTarget::MODULE_LIBRARY)
|
||||
target.GetType() == cmTarget::MODULE_LIBRARY ||
|
||||
target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
|
||||
{
|
||||
|
|
|
@ -1367,16 +1367,18 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// This function removes each occurence of the flag and returns the last one
|
||||
// This function removes each occurrence of the flag and returns the last one
|
||||
// (i.e., the dominant flag in GCC)
|
||||
std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
|
||||
std::string& flags)
|
||||
{
|
||||
std::string retFlag;
|
||||
std::string::size_type pos = flags.rfind(flag);
|
||||
std::string::size_type lastOccurancePos = flags.rfind(flag);
|
||||
bool saved = false;
|
||||
while(pos != flags.npos)
|
||||
while(lastOccurancePos != flags.npos)
|
||||
{
|
||||
//increment pos, we use lastOccurancePos to reduce search space on next inc
|
||||
std::string::size_type pos = lastOccurancePos;
|
||||
if(pos == 0 || flags[pos-1]==' ')
|
||||
{
|
||||
while(pos < flags.size() && flags[pos] != ' ')
|
||||
|
@ -1388,9 +1390,12 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
|
|||
flags[pos] = ' ';
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
saved = true;
|
||||
pos = flags.rfind(flag);
|
||||
}
|
||||
//decrement lastOccurancePos while making sure we don't loop around
|
||||
//and become a very large positive number since size_type is unsigned
|
||||
lastOccurancePos = lastOccurancePos == 0 ? 0 : lastOccurancePos-1;
|
||||
lastOccurancePos = flags.rfind(flag,lastOccurancePos);
|
||||
}
|
||||
return retFlag;
|
||||
}
|
||||
|
@ -1676,11 +1681,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
this->AppendDefines(ppDefs, exportMacro);
|
||||
}
|
||||
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
|
||||
this->AppendDefines(ppDefs, gtgt->GetCompileDefinitions().c_str());
|
||||
this->AppendDefines(ppDefs, target.GetCompileDefinitions().c_str());
|
||||
if(configName)
|
||||
{
|
||||
this->AppendDefines(ppDefs,
|
||||
gtgt->GetCompileDefinitions(configName).c_str());
|
||||
target.GetCompileDefinitions(configName).c_str());
|
||||
}
|
||||
buildSettings->AddAttribute
|
||||
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
|
||||
|
|
|
@ -36,6 +36,10 @@ bool cmIncludeDirectoryCommand
|
|||
++i;
|
||||
}
|
||||
|
||||
std::vector<std::string> beforeIncludes;
|
||||
std::vector<std::string> afterIncludes;
|
||||
std::set<cmStdString> systemIncludes;
|
||||
|
||||
for(; i != args.end(); ++i)
|
||||
{
|
||||
if(*i == "SYSTEM")
|
||||
|
@ -49,9 +53,37 @@ bool cmIncludeDirectoryCommand
|
|||
return false;
|
||||
}
|
||||
|
||||
this->AddDirectory(i->c_str(),before,system);
|
||||
std::vector<std::string> includes;
|
||||
|
||||
GetIncludes(*i, includes);
|
||||
|
||||
if (before)
|
||||
{
|
||||
beforeIncludes.insert(beforeIncludes.end(),
|
||||
includes.begin(),
|
||||
includes.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
afterIncludes.insert(afterIncludes.end(),
|
||||
includes.begin(),
|
||||
includes.end());
|
||||
}
|
||||
if (system)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator li = includes.begin();
|
||||
li != includes.end(); ++li)
|
||||
{
|
||||
systemIncludes.insert(*li);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::reverse(beforeIncludes.begin(), beforeIncludes.end());
|
||||
|
||||
this->Makefile->AddIncludeDirectories(afterIncludes);
|
||||
this->Makefile->AddIncludeDirectories(beforeIncludes, before);
|
||||
this->Makefile->AddSystemIncludeDirectories(systemIncludes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -72,57 +104,49 @@ static bool StartsWithGeneratorExpression(const std::string &input)
|
|||
// output from a program and passing it into a command the cleanup doesn't
|
||||
// always happen
|
||||
//
|
||||
void cmIncludeDirectoryCommand::AddDirectory(const char *i,
|
||||
bool before,
|
||||
bool system)
|
||||
void cmIncludeDirectoryCommand::GetIncludes(const std::string &arg,
|
||||
std::vector<std::string> &incs)
|
||||
{
|
||||
// break apart any line feed arguments
|
||||
std::string ret = i;
|
||||
std::string::size_type pos = 0;
|
||||
if((pos = ret.find('\n', pos)) != std::string::npos)
|
||||
std::string::size_type lastPos = 0;
|
||||
while((pos = arg.find('\n', lastPos)) != std::string::npos)
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
this->AddDirectory(ret.substr(0,pos).c_str(), before, system);
|
||||
std::string inc = arg.substr(lastPos,pos);
|
||||
NormalizeInclude(inc);
|
||||
incs.push_back(inc);
|
||||
}
|
||||
if (ret.size()-pos-1)
|
||||
{
|
||||
this->AddDirectory(ret.substr(pos+1,ret.size()-pos-1).c_str(),
|
||||
before, system);
|
||||
}
|
||||
return;
|
||||
lastPos = pos + 1;
|
||||
}
|
||||
std::string inc = arg.substr(lastPos);
|
||||
NormalizeInclude(inc);
|
||||
incs.push_back(inc);
|
||||
}
|
||||
|
||||
void cmIncludeDirectoryCommand::NormalizeInclude(std::string &inc)
|
||||
{
|
||||
std::string::size_type b = inc.find_first_not_of(" \r");
|
||||
std::string::size_type e = inc.find_last_not_of(" \r");
|
||||
if ((b!=inc.npos) && (e!=inc.npos))
|
||||
{
|
||||
inc.assign(inc, b, 1+e-b); // copy the remaining substring
|
||||
}
|
||||
|
||||
// remove any leading or trailing spaces and \r
|
||||
std::string::size_type b = ret.find_first_not_of(" \r");
|
||||
std::string::size_type e = ret.find_last_not_of(" \r");
|
||||
if ((b!=ret.npos) && (e!=ret.npos))
|
||||
if (!cmSystemTools::IsOff(inc.c_str()))
|
||||
{
|
||||
ret.assign(ret, b, 1+e-b); // copy the remaining substring
|
||||
}
|
||||
else
|
||||
{
|
||||
return; // if we get here, we had only whitespace in the string
|
||||
}
|
||||
cmSystemTools::ConvertToUnixSlashes(inc);
|
||||
|
||||
if (!cmSystemTools::IsOff(ret.c_str()))
|
||||
{
|
||||
cmSystemTools::ConvertToUnixSlashes(ret);
|
||||
if(!cmSystemTools::FileIsFullPath(ret.c_str()))
|
||||
if(!cmSystemTools::FileIsFullPath(inc.c_str()))
|
||||
{
|
||||
if(!StartsWithGeneratorExpression(ret))
|
||||
if(!StartsWithGeneratorExpression(inc))
|
||||
{
|
||||
std::string tmp = this->Makefile->GetStartDirectory();
|
||||
tmp += "/";
|
||||
tmp += ret;
|
||||
ret = tmp;
|
||||
tmp += inc;
|
||||
inc = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->Makefile->AddIncludeDirectory(ret.c_str(), before);
|
||||
if(system)
|
||||
{
|
||||
this->Makefile->AddSystemIncludeDirectory(ret.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,8 @@ public:
|
|||
|
||||
protected:
|
||||
// used internally
|
||||
void AddDirectory(const char *arg, bool before, bool system);
|
||||
void GetIncludes(const std::string &arg, std::vector<std::string> &incs);
|
||||
void NormalizeInclude(std::string &inc);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1697,25 +1697,21 @@ void cmLocalVisualStudio6Generator
|
|||
std::set<std::string> minsizeDefinesSet;
|
||||
std::set<std::string> debugrelDefinesSet;
|
||||
|
||||
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
|
||||
this->AppendDefines(
|
||||
definesSet,
|
||||
gt->GetCompileDefinitions());
|
||||
target.GetCompileDefinitions());
|
||||
this->AppendDefines(
|
||||
debugDefinesSet,
|
||||
gt->GetCompileDefinitions("DEBUG"));
|
||||
target.GetCompileDefinitions("DEBUG"));
|
||||
this->AppendDefines(
|
||||
releaseDefinesSet,
|
||||
gt->GetCompileDefinitions("RELEASE"));
|
||||
target.GetCompileDefinitions("RELEASE"));
|
||||
this->AppendDefines(
|
||||
minsizeDefinesSet,
|
||||
gt->GetCompileDefinitions("MINSIZEREL"));
|
||||
target.GetCompileDefinitions("MINSIZEREL"));
|
||||
this->AppendDefines(
|
||||
debugrelDefinesSet,
|
||||
gt->GetCompileDefinitions("RELWITHDEBINFO"));
|
||||
target.GetCompileDefinitions("RELWITHDEBINFO"));
|
||||
|
||||
std::string defines = " ";
|
||||
std::string debugDefines = " ";
|
||||
|
|
|
@ -745,8 +745,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
targetOptions.ParseFinish();
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
targetOptions.AddDefines(gt->GetCompileDefinitions().c_str());
|
||||
targetOptions.AddDefines(gt->GetCompileDefinitions(configName).c_str());
|
||||
targetOptions.AddDefines(target.GetCompileDefinitions().c_str());
|
||||
targetOptions.AddDefines(target.GetCompileDefinitions(configName).c_str());
|
||||
targetOptions.SetVerboseMakefile(
|
||||
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ cmMakefile::cmMakefile(): Internal(new Internals)
|
|||
this->AddDefaultDefinitions();
|
||||
this->Initialize();
|
||||
this->PreOrder = false;
|
||||
this->GeneratingBuildSystem = false;
|
||||
}
|
||||
|
||||
cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
|
||||
|
@ -1616,20 +1617,31 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
|
||||
void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
|
||||
bool before)
|
||||
{
|
||||
if (!inc)
|
||||
if (incs.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string incString;
|
||||
std::string sep;
|
||||
|
||||
for(std::vector<std::string>::const_iterator li = incs.begin();
|
||||
li != incs.end(); ++li)
|
||||
{
|
||||
incString += sep + *li;
|
||||
sep = ";";
|
||||
}
|
||||
|
||||
std::vector<IncludeDirectoriesEntry>::iterator position =
|
||||
before ? this->IncludeDirectoriesEntries.begin()
|
||||
: this->IncludeDirectoriesEntries.end();
|
||||
before ? this->IncludeDirectoriesEntries.begin()
|
||||
: this->IncludeDirectoriesEntries.end();
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
this->GetBacktrace(lfbt);
|
||||
IncludeDirectoriesEntry entry(inc, lfbt);
|
||||
IncludeDirectoriesEntry entry(incString, lfbt);
|
||||
this->IncludeDirectoriesEntries.insert(position, entry);
|
||||
|
||||
// Property on each target:
|
||||
|
@ -1642,9 +1654,14 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefile::AddSystemIncludeDirectory(const char* dir)
|
||||
void
|
||||
cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
|
||||
{
|
||||
this->SystemIncludeDirectories.insert(dir);
|
||||
for(std::set<cmStdString>::const_iterator li = incs.begin();
|
||||
li != incs.end(); ++li)
|
||||
{
|
||||
this->SystemIncludeDirectories.insert(*li);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -2243,7 +2260,7 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
// If we are doing an in-source build, than the test will always fail
|
||||
// If we are doing an in-source build, then the test will always fail
|
||||
if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
|
||||
this->GetHomeOutputDirectory()) )
|
||||
{
|
||||
|
@ -2254,8 +2271,8 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Check if this is subdirectory of the source tree but not a
|
||||
// subdirectory of a build tree
|
||||
// Check if this is a subdirectory of the source tree but not a
|
||||
// subdirectory of the build tree
|
||||
if ( cmSystemTools::IsSubDirectory(fileName,
|
||||
this->GetHomeDirectory()) &&
|
||||
!cmSystemTools::IsSubDirectory(fileName,
|
||||
|
|
|
@ -287,7 +287,8 @@ public:
|
|||
/**
|
||||
* Add an include directory to the build.
|
||||
*/
|
||||
void AddIncludeDirectory(const char*, bool before = false);
|
||||
void AddIncludeDirectories(const std::vector<std::string> &incs,
|
||||
bool before = false);
|
||||
|
||||
/**
|
||||
* Add a variable definition to the build. This variable
|
||||
|
@ -545,7 +546,7 @@ public:
|
|||
/**
|
||||
* Mark include directories as system directories.
|
||||
*/
|
||||
void AddSystemIncludeDirectory(const char* dir);
|
||||
void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
|
||||
bool IsSystemIncludeDirectory(const char* dir);
|
||||
|
||||
/** Expand out any arguements in the vector that have ; separated
|
||||
|
@ -869,6 +870,9 @@ public:
|
|||
return this->IncludeDirectoriesEntries;
|
||||
}
|
||||
|
||||
bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
|
||||
void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
|
||||
|
||||
protected:
|
||||
// add link libraries and directories to the target
|
||||
void AddGlobalLinkInformation(const char* name, cmTarget& target);
|
||||
|
@ -1018,6 +1022,9 @@ private:
|
|||
|
||||
// Enforce rules about CMakeLists.txt files.
|
||||
void EnforceDirectoryLevelRules();
|
||||
|
||||
bool GeneratingBuildSystem;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -303,10 +303,10 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
|
|||
|
||||
// Add preprocessor definitions for this target and configuration.
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines, this->GeneratorTarget->GetCompileDefinitions());
|
||||
(defines, this->Target->GetCompileDefinitions());
|
||||
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines, this->GeneratorTarget->GetCompileDefinitions(
|
||||
(defines, this->Target->GetCompileDefinitions(
|
||||
this->LocalGenerator->ConfigurationName.c_str()));
|
||||
|
||||
std::string definesString;
|
||||
|
|
|
@ -228,7 +228,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
|
|||
// Add preprocessor definitions for this target and configuration.
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
this->GeneratorTarget->GetCompileDefinitions());
|
||||
this->Target->GetCompileDefinitions());
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
source->GetProperty("COMPILE_DEFINITIONS"));
|
||||
|
@ -237,7 +237,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
|
|||
defPropName += cmSystemTools::UpperCase(this->GetConfigName());
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName()));
|
||||
this->Target->GetCompileDefinitions(this->GetConfigName()));
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
source->GetProperty(defPropName.c_str()));
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -229,7 +229,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
|
|||
}
|
||||
|
||||
const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");
|
||||
std::string _moc_compile_defs = (tmp!=0 ? tmp : "");
|
||||
std::string _moc_compile_defs;
|
||||
if (tmp)
|
||||
{
|
||||
_moc_compile_defs = target->GetCompileDefinitions();
|
||||
}
|
||||
tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
|
||||
if (tmp)
|
||||
{
|
||||
|
|
|
@ -145,11 +145,14 @@ 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;
|
||||
this->IsApple = false;
|
||||
this->IsImportedTarget = false;
|
||||
this->BuildInterfaceIncludesAppended = false;
|
||||
this->DebugIncludesDone = false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -891,6 +894,30 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||
"must ensure that the targets that they link to have a consistent "
|
||||
"requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
|
||||
|
||||
cm->DefineProperty
|
||||
("COMPATIBLE_INTERFACE_BOOL", cmProperty::TARGET,
|
||||
"Properties which must be compatible with their link interface",
|
||||
"The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
|
||||
"for this target which must be consistent when evaluated as a boolean "
|
||||
"in the INTERFACE of all linked dependencies. For example, if a "
|
||||
"property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
|
||||
"property content in all dependencies must be consistent with each "
|
||||
"other, and with the \"FOO\" property in this target. "
|
||||
"Consistency in this sense has the meaning that if the property is set,"
|
||||
"then it must have the same boolean value as all others, and if the "
|
||||
"property is not set, then it is ignored.");
|
||||
|
||||
cm->DefineProperty
|
||||
("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
|
||||
"Properties which must be string-compatible with their link interface",
|
||||
"The COMPATIBLE_INTERFACE_STRING property may contain a list of "
|
||||
"properties for this target which must be the same when evaluated as "
|
||||
"a string in the INTERFACE of all linked dependencies. For example, "
|
||||
"if a property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
|
||||
"property content in all dependencies must be equal with each "
|
||||
"other, and with the \"FOO\" property in this target. If the "
|
||||
"property is not set, then it is ignored.");
|
||||
|
||||
cm->DefineProperty
|
||||
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
|
||||
"Deprecated install support.",
|
||||
|
@ -1485,6 +1512,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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1506,6 +1535,13 @@ void cmTarget::ClearLinkMaps()
|
|||
this->Internal->LinkImplMap.clear();
|
||||
this->Internal->LinkInterfaceMap.clear();
|
||||
this->Internal->LinkClosureMap.clear();
|
||||
for (cmTargetLinkInformationMap::const_iterator it
|
||||
= this->LinkInformation.begin();
|
||||
it != this->LinkInformation.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
this->LinkInformation.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -2232,6 +2268,14 @@ static std::string targetNameGenex(const char *lib)
|
|||
return std::string("$<TARGET_NAME:") + lib + ">";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool isGeneratorExpression(const std::string &lib)
|
||||
{
|
||||
const std::string::size_type openpos = lib.find("$<");
|
||||
return (openpos != std::string::npos)
|
||||
&& (lib.find(">", openpos) != std::string::npos);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
||||
const char *target, const char* lib,
|
||||
|
@ -2247,13 +2291,19 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
|||
cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
|
||||
const bool isNonImportedTarget = tgt && !tgt->IsImported();
|
||||
|
||||
std::string libName = isNonImportedTarget ? targetNameGenex(lib)
|
||||
: std::string(lib);
|
||||
const std::string libName = (isNonImportedTarget && llt != GENERAL)
|
||||
? targetNameGenex(lib)
|
||||
: std::string(lib);
|
||||
this->AppendProperty("LINK_LIBRARIES",
|
||||
this->GetDebugGeneratorExpressions(libName,
|
||||
llt).c_str());
|
||||
}
|
||||
|
||||
if (isGeneratorExpression(lib))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cmTarget::LibraryID tmp;
|
||||
tmp.first = lib;
|
||||
tmp.second = llt;
|
||||
|
@ -2654,6 +2704,30 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
|
|||
this->MaybeInvalidatePropertyCache(prop);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::AppendBuildInterfaceIncludes()
|
||||
{
|
||||
if (this->BuildInterfaceIncludesAppended)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->BuildInterfaceIncludesAppended = true;
|
||||
|
||||
if (this->Makefile->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
|
||||
{
|
||||
const char *binDir = this->Makefile->GetStartOutputDirectory();
|
||||
const char *srcDir = this->Makefile->GetStartDirectory();
|
||||
const std::string dirs = std::string(binDir ? binDir : "")
|
||||
+ std::string(binDir ? ";" : "")
|
||||
+ std::string(srcDir ? srcDir : "");
|
||||
if (!dirs.empty())
|
||||
{
|
||||
this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
||||
("$<BUILD_INTERFACE:" + dirs + ">").c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
||||
bool before)
|
||||
|
@ -2688,11 +2762,17 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
|
|||
cmSystemTools::ExpandListArgument(debugProp, debugProperties);
|
||||
}
|
||||
|
||||
bool debugIncludes = std::find(debugProperties.begin(),
|
||||
bool debugIncludes = !this->DebugIncludesDone
|
||||
&& std::find(debugProperties.begin(),
|
||||
debugProperties.end(),
|
||||
"INCLUDE_DIRECTORIES")
|
||||
!= debugProperties.end();
|
||||
|
||||
if (this->Makefile->IsGeneratingBuildSystem())
|
||||
{
|
||||
this->DebugIncludesDone = true;
|
||||
}
|
||||
|
||||
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
|
||||
it = this->Internal->IncludeDirectoriesEntries.begin(),
|
||||
end = this->Internal->IncludeDirectoriesEntries.end();
|
||||
|
@ -2727,13 +2807,42 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
|
|||
if (!usedIncludes.empty())
|
||||
{
|
||||
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,
|
||||
"Used includes:\n" + usedIncludes,
|
||||
(*it)->ge->GetBacktrace());
|
||||
"Used includes for target " + this->Name + ":\n"
|
||||
+ usedIncludes, (*it)->ge->GetBacktrace());
|
||||
}
|
||||
}
|
||||
return includes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTarget::GetCompileDefinitions(const char *config)
|
||||
{
|
||||
std::string defPropName = "COMPILE_DEFINITIONS";
|
||||
if (config)
|
||||
{
|
||||
defPropName += "_" + cmSystemTools::UpperCase(config);
|
||||
}
|
||||
|
||||
const char *prop = this->GetProperty(defPropName.c_str());
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
defPropName, 0, 0);
|
||||
return ge.Parse(prop)->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this,
|
||||
&dagChecker);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
|
||||
{
|
||||
|
@ -4431,22 +4540,69 @@ void cmTarget::AddLinkDependentTargetsForProperties(
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config)
|
||||
template<typename PropertyType>
|
||||
PropertyType getTypedProperty(cmTarget *tgt, const char *prop,
|
||||
PropertyType *);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
|
||||
{
|
||||
bool propContent = this->GetPropertyAsBool(p.c_str());
|
||||
const bool explicitlySet = this->GetProperties()
|
||||
return tgt->GetPropertyAsBool(prop);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
|
||||
const char **)
|
||||
{
|
||||
return tgt->GetProperty(prop);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
bool consistentProperty(PropertyType lhs, PropertyType rhs);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool consistentProperty(bool lhs, bool rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool consistentProperty(const char *lhs, const char *rhs)
|
||||
{
|
||||
if (!lhs && !rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
||||
const std::string &p,
|
||||
const char *config,
|
||||
const char *defaultValue,
|
||||
PropertyType *)
|
||||
{
|
||||
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
|
||||
0);
|
||||
const bool explicitlySet = tgt->GetProperties()
|
||||
.find(p.c_str())
|
||||
!= this->GetProperties().end();
|
||||
!= tgt->GetProperties().end();
|
||||
std::set<std::string> dependentTargets;
|
||||
this->GetLinkDependentTargetsForProperty(p,
|
||||
tgt->GetLinkDependentTargetsForProperty(p,
|
||||
dependentTargets);
|
||||
const bool impliedByUse =
|
||||
this->IsNullImpliedByLinkLibraries(p);
|
||||
tgt->IsNullImpliedByLinkLibraries(p);
|
||||
assert((impliedByUse ^ explicitlySet)
|
||||
|| (!impliedByUse && !explicitlySet));
|
||||
|
||||
cmComputeLinkInformation *info = this->GetLinkInformation(config);
|
||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
bool propInitialized = explicitlySet;
|
||||
|
||||
|
@ -4468,20 +4624,22 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
const bool ifaceIsSet = li->Target->GetProperties()
|
||||
.find("INTERFACE_" + p)
|
||||
!= li->Target->GetProperties().end();
|
||||
const bool ifacePropContent = li->Target->GetPropertyAsBool(
|
||||
("INTERFACE_" + p).c_str());
|
||||
PropertyType ifacePropContent =
|
||||
getTypedProperty<PropertyType>(li->Target,
|
||||
("INTERFACE_" + p).c_str(), 0);
|
||||
if (explicitlySet)
|
||||
{
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
if (propContent != ifacePropContent)
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Property " << p << " on target \""
|
||||
<< this->GetName() << "\" does\nnot match the "
|
||||
<< tgt->GetName() << "\" does\nnot match the "
|
||||
"INTERFACE_" << p << " property requirement\nof "
|
||||
"dependency \"" << li->Target->GetName() << "\".\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4499,15 +4657,16 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
{
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
if (propContent != ifacePropContent)
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Property " << p << " on target \""
|
||||
<< this->GetName() << "\" is\nimplied to be FALSE because it "
|
||||
"was used to determine the link libraries\nalready. The "
|
||||
"INTERFACE_" << p << " property on\ndependency \""
|
||||
<< tgt->GetName() << "\" is\nimplied to be " << defaultValue
|
||||
<< " because it was used to determine the link libraries\n"
|
||||
"already. The INTERFACE_" << p << " property on\ndependency \""
|
||||
<< li->Target->GetName() << "\" is in conflict.\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4527,14 +4686,15 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
{
|
||||
if (propInitialized)
|
||||
{
|
||||
if (propContent != ifacePropContent)
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "The INTERFACE_" << p << " property of \""
|
||||
<< li->Target->GetName() << "\" does\nnot agree with the value "
|
||||
"of " << p << " already determined\nfor \""
|
||||
<< this->GetName() << "\".\n";
|
||||
<< tgt->GetName() << "\".\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4558,6 +4718,80 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
return propContent;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
|
||||
0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char * cmTarget::GetLinkInterfaceDependentStringProperty(
|
||||
const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return checkInterfacePropertyCompatibility<const char *>(this,
|
||||
p,
|
||||
config,
|
||||
"empty", 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
|
||||
const char *interfaceProperty,
|
||||
const char *config)
|
||||
{
|
||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char *prop = li->Target->GetProperty(interfaceProperty);
|
||||
if (!prop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> props;
|
||||
cmSystemTools::ExpandListArgument(prop, props);
|
||||
|
||||
for(std::vector<std::string>::iterator pi = props.begin();
|
||||
pi != props.end(); ++pi)
|
||||
{
|
||||
if (*pi == p)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
|
||||
config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
|
||||
config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
||||
{
|
||||
|
@ -4896,16 +5130,30 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
|
|||
{
|
||||
std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
|
||||
linkProp += suffix;
|
||||
if(const char* config_libs = this->GetProperty(linkProp.c_str()))
|
||||
|
||||
const char *propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
|
||||
if(!propertyLibs)
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(config_libs,
|
||||
info.LinkInterface.Libraries);
|
||||
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
|
||||
propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
}
|
||||
else if(const char* libs =
|
||||
this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
|
||||
if(propertyLibs)
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(libs,
|
||||
info.LinkInterface.Libraries);
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
linkProp, 0, 0);
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
|
||||
->Evaluate(this->Makefile,
|
||||
desired_config.c_str(),
|
||||
false,
|
||||
headTarget,
|
||||
this,
|
||||
&dagChecker),
|
||||
info.LinkInterface.Libraries);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5019,18 +5267,20 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
// An explicit list of interface libraries may be set for shared
|
||||
// libraries and executables that export symbols.
|
||||
const char* explicitLibraries = 0;
|
||||
std::string linkIfaceProp;
|
||||
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
this->IsExecutableWithExports())
|
||||
{
|
||||
// Lookup the per-configuration property.
|
||||
std::string propName = "LINK_INTERFACE_LIBRARIES";
|
||||
propName += suffix;
|
||||
explicitLibraries = this->GetProperty(propName.c_str());
|
||||
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
|
||||
linkIfaceProp += suffix;
|
||||
explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
|
||||
|
||||
// If not set, try the generic property.
|
||||
if(!explicitLibraries)
|
||||
{
|
||||
explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES");
|
||||
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
|
||||
explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5048,7 +5298,16 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
if(explicitLibraries)
|
||||
{
|
||||
// The interface libraries have been explicitly set.
|
||||
cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
|
||||
linkIfaceProp, 0, 0);
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
|
||||
this->Makefile,
|
||||
config,
|
||||
false,
|
||||
headTarget,
|
||||
this, &dagChecker), iface.Libraries);
|
||||
|
||||
if(this->GetType() == cmTarget::SHARED_LIBRARY)
|
||||
{
|
||||
|
@ -5091,6 +5350,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
// The link implementation is the default link interface.
|
||||
LinkImplementation const* impl = this->GetLinkImplementation(config,
|
||||
headTarget);
|
||||
iface.ImplementationIsInterface = true;
|
||||
iface.Libraries = impl->Libraries;
|
||||
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
|
||||
if(this->GetType() == cmTarget::STATIC_LIBRARY)
|
||||
|
@ -5272,6 +5532,107 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
|
|||
return lib;
|
||||
}
|
||||
|
||||
template<typename PropertyType>
|
||||
PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
PropertyType *);
|
||||
|
||||
template<>
|
||||
bool getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config, bool *)
|
||||
{
|
||||
return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
|
||||
}
|
||||
|
||||
template<>
|
||||
const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
const char **)
|
||||
{
|
||||
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
|
||||
const char *propName,
|
||||
std::set<cmStdString> &emitted,
|
||||
const char *config,
|
||||
PropertyType *)
|
||||
{
|
||||
const char *prop = dependee->GetProperty(propName);
|
||||
if (!prop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> props;
|
||||
cmSystemTools::ExpandListArgument(prop, props);
|
||||
|
||||
for(std::vector<std::string>::iterator pi = props.begin();
|
||||
pi != props.end(); ++pi)
|
||||
{
|
||||
if (depender->GetMakefile()->GetCMakeInstance()
|
||||
->GetIsPropertyDefined(pi->c_str(),
|
||||
cmProperty::TARGET))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << dependee->GetName() << "\" has property \""
|
||||
<< *pi << "\" listed in its " << propName << " property. "
|
||||
"This is not allowed. Only user-defined properties may appear "
|
||||
"listed in the " << propName << " property.";
|
||||
depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
if(emitted.insert(*pi).second)
|
||||
{
|
||||
getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
|
||||
0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||
const char* config)
|
||||
{
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
|
||||
std::set<cmStdString> emitted;
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
checkPropertyConsistency<bool>(this, li->Target,
|
||||
"COMPATIBLE_INTERFACE_BOOL",
|
||||
emitted, config, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
checkPropertyConsistency<const char *>(this, li->Target,
|
||||
"COMPATIBLE_INTERFACE_STRING",
|
||||
emitted, config, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmComputeLinkInformation*
|
||||
cmTarget::GetLinkInformation(const char* config, cmTarget *head)
|
||||
|
@ -5296,6 +5657,11 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
|
|||
// Store the information for this configuration.
|
||||
cmTargetLinkInformationMap::value_type entry(key, info);
|
||||
i = this->LinkInformation.insert(entry).first;
|
||||
|
||||
if (info)
|
||||
{
|
||||
this->CheckPropertyCompatibility(info, config);
|
||||
}
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
@ -258,7 +262,9 @@ public:
|
|||
// Needed only for OLD behavior of CMP0003.
|
||||
std::vector<std::string> WrongConfigLibraries;
|
||||
|
||||
LinkInterface(): Multiplicity(0) {}
|
||||
bool ImplementationIsInterface;
|
||||
|
||||
LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
|
||||
};
|
||||
|
||||
/** Get the link interface for the given configuration. Returns 0
|
||||
|
@ -424,6 +430,8 @@ public:
|
|||
If no macro should be defined null is returned. */
|
||||
const char* GetExportMacro();
|
||||
|
||||
std::string GetCompileDefinitions(const char *config = 0);
|
||||
|
||||
// Compute the set of languages compiled by the target. This is
|
||||
// computed every time it is called because the languages can change
|
||||
// when source file properties are changed and we do not have enough
|
||||
|
@ -488,15 +496,24 @@ public:
|
|||
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
||||
bool before = false);
|
||||
|
||||
void AppendBuildInterfaceIncludes();
|
||||
|
||||
void GetLinkDependentTargetsForProperty(const std::string &p,
|
||||
std::set<std::string> &targets);
|
||||
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
||||
bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config);
|
||||
bool IsLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config);
|
||||
|
||||
void AddLinkDependentTargetsForProperties(
|
||||
const std::map<cmStdString, cmStdString> &map);
|
||||
|
||||
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config);
|
||||
|
||||
const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config);
|
||||
private:
|
||||
/**
|
||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||
|
@ -606,9 +623,11 @@ private:
|
|||
bool DLLPlatform;
|
||||
bool IsApple;
|
||||
bool IsImportedTarget;
|
||||
bool DebugIncludesDone;
|
||||
mutable std::map<cmStdString, std::set<std::string> >
|
||||
LinkDependentProperties;
|
||||
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||
bool BuildInterfaceIncludesAppended;
|
||||
|
||||
// Cache target output paths for each configuration.
|
||||
struct OutputInfo;
|
||||
|
@ -624,6 +643,8 @@ private:
|
|||
cmTarget *head);
|
||||
|
||||
cmTargetLinkInformationMap LinkInformation;
|
||||
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||
const char* config);
|
||||
|
||||
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||
cmTarget *head);
|
||||
|
@ -649,6 +670,7 @@ private:
|
|||
cmPolicies::PolicyStatus PolicyStatusCMP0003;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0004;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0008;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0020;
|
||||
|
||||
// Internal representation details.
|
||||
friend class cmTargetInternals;
|
||||
|
|
|
@ -20,13 +20,11 @@ bool cmTargetCompileDefinitionsCommand
|
|||
}
|
||||
|
||||
void cmTargetCompileDefinitionsCommand
|
||||
::HandleImportedTargetInvalidScope(const std::string &scope,
|
||||
const std::string &tgt)
|
||||
::HandleImportedTarget(const std::string &tgt)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify " << scope << " compile definitions for imported "
|
||||
"target \"" << tgt << "\". Compile definitions can only be "
|
||||
"specified for an imported target in the INTERFACE mode.";
|
||||
e << "Cannot specify compile definitions for imported target \""
|
||||
<< tgt << "\".";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
"Specify compile definitions or targets to use when compiling a given "
|
||||
"target. "
|
||||
"The named <target> must have been created by a command such as "
|
||||
"add_executable or add_library. "
|
||||
"add_executable or add_library and must not be an IMPORTED target. "
|
||||
"The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
|
||||
"the scope of the following arguments. PRIVATE and PUBLIC items will "
|
||||
"populate the COMPILE_DEFINITIONS property of <target>. PUBLIC and "
|
||||
|
@ -69,14 +69,16 @@ public:
|
|||
"INTERFACE_COMPILE_DEFINITIONS from. "
|
||||
"Repeated calls for the same <target> append items in the order called."
|
||||
"\n"
|
||||
"Arguments to target_compile_definitions may use \"generator "
|
||||
"expressions\" with the syntax \"$<...>\". "
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmTargetCompileDefinitionsCommand, cmCommand);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &scope,
|
||||
const std::string &tgt);
|
||||
virtual void HandleImportedTarget(const std::string &tgt);
|
||||
virtual void HandleMissingTarget(const std::string &name);
|
||||
|
||||
virtual bool HandleNonTargetArg(std::string &content,
|
||||
|
|
|
@ -22,13 +22,11 @@ bool cmTargetIncludeDirectoriesCommand
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetIncludeDirectoriesCommand
|
||||
::HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope)
|
||||
::HandleImportedTarget(const std::string &tgt)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify " << scope << " include directories for imported "
|
||||
"target \"" << tgt << "\". Include directories can only be "
|
||||
"specified for an imported target in the INTERFACE mode.";
|
||||
e << "Cannot specify include directories for imported target \""
|
||||
<< tgt << "\".";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
"Specify include directories or targets to use when compiling a given "
|
||||
"target. "
|
||||
"The named <target> must have been created by a command such as "
|
||||
"add_executable or add_library.\n"
|
||||
"add_executable or add_library and must not be an IMPORTED target.\n"
|
||||
"If BEFORE is specified, the content will be prepended to the property "
|
||||
"instead of being appended.\n"
|
||||
"The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
|
||||
|
@ -73,14 +73,16 @@ public:
|
|||
"directories must be absolute paths, not relative paths. "
|
||||
"Repeated calls for the same <target> append items in the order called."
|
||||
"\n"
|
||||
"Arguments to target_include_directories may use \"generator "
|
||||
"expressions\" with the syntax \"$<...>\". "
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmCommand);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope);
|
||||
virtual void HandleImportedTarget(const std::string &tgt);
|
||||
virtual void HandleMissingTarget(const std::string &name);
|
||||
|
||||
virtual bool HandleNonTargetArg(std::string &content,
|
||||
|
|
|
@ -33,10 +33,6 @@ bool cmTargetLinkLibrariesCommand
|
|||
this->Target =
|
||||
this->Makefile->GetCMakeInstance()
|
||||
->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
|
||||
if(!this->Target)
|
||||
{
|
||||
this->Target = this->Makefile->FindTargetToUse(args[0].c_str());
|
||||
}
|
||||
if(!this->Target)
|
||||
{
|
||||
cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
|
||||
|
@ -261,16 +257,6 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
|||
// Handle normal case first.
|
||||
if(this->CurrentProcessingState != ProcessingLinkInterface)
|
||||
{
|
||||
if (this->Target->IsImported())
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Imported targets may only be used with the "
|
||||
"LINK_INTERFACE_LIBRARIES specifier to target_link_libraries.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this->Makefile
|
||||
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
|
||||
if (this->CurrentProcessingState != ProcessingPublicInterface)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define cmTargetLinkLibrariesCommand_h
|
||||
|
||||
#include "cmCommand.h"
|
||||
#include "cmDocumentGeneratorExpressions.h"
|
||||
|
||||
/** \class cmTargetLinkLibrariesCommand
|
||||
* \brief Specify a list of libraries to link into executables.
|
||||
|
@ -92,7 +93,9 @@ public:
|
|||
"linked to this target will appear on the link line for the other "
|
||||
"target too. "
|
||||
"See the LINK_INTERFACE_LIBRARIES target property to override the "
|
||||
"set of transitive link dependencies for a target."
|
||||
"set of transitive link dependencies for a target. "
|
||||
"Calls to other signatures of this command may set the property "
|
||||
"making any libraries linked exclusively by this signature private."
|
||||
"\n"
|
||||
" target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
|
||||
" [[debug|optimized|general] <lib>] ...)\n"
|
||||
|
@ -141,6 +144,12 @@ public:
|
|||
"However, if two archives are really so interdependent they should "
|
||||
"probably be combined into a single archive."
|
||||
")"
|
||||
"\n"
|
||||
"Arguments to target_link_libraries may use \"generator expressions\" "
|
||||
"with the syntax \"$<...>\". Note however, that generator expressions "
|
||||
"will not be used in OLD handling of CMP0003 or CMP0004."
|
||||
"\n"
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,14 @@ bool cmTargetPropCommandBase
|
|||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool isGeneratorExpression(const std::string &lib)
|
||||
{
|
||||
const std::string::size_type openpos = lib.find("$<");
|
||||
return (openpos != std::string::npos)
|
||||
&& (lib.find(">", openpos) != std::string::npos);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTargetPropCommandBase
|
||||
::ProcessContentArgs(std::vector<std::string> const& args,
|
||||
|
@ -80,9 +88,9 @@ bool cmTargetPropCommandBase
|
|||
return false;
|
||||
}
|
||||
|
||||
if(this->Target->IsImported() && scope != "INTERFACE")
|
||||
if(this->Target->IsImported())
|
||||
{
|
||||
this->HandleImportedTargetInvalidScope(args[0], scope);
|
||||
this->HandleImportedTarget(args[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -105,6 +113,10 @@ bool cmTargetPropCommandBase
|
|||
content += sep + "$<TARGET_PROPERTY:" + args[i]
|
||||
+ ",INTERFACE_" + this->Property + ">";
|
||||
}
|
||||
else if(isGeneratorExpression(args[i]))
|
||||
{
|
||||
content += sep + args[i];
|
||||
}
|
||||
else if (!this->HandleNonTargetArg(content, sep, args[i], args[0]))
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define cmTargetPropCommandBase_h
|
||||
|
||||
#include "cmCommand.h"
|
||||
#include "cmDocumentGeneratorExpressions.h"
|
||||
|
||||
class cmTarget;
|
||||
|
||||
|
@ -31,8 +32,7 @@ public:
|
|||
const char *prop, ArgumentFlags flags = NO_FLAGS);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope) = 0;
|
||||
virtual void HandleImportedTarget(const std::string &tgt) = 0;
|
||||
virtual void HandleMissingTarget(const std::string &name) = 0;
|
||||
|
||||
virtual bool HandleNonTargetArg(std::string &content,
|
||||
|
|
|
@ -1221,8 +1221,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
|
|||
clOptions.Parse(flags.c_str());
|
||||
clOptions.Parse(defineFlags.c_str());
|
||||
clOptions.AddDefines(
|
||||
this->GeneratorTarget->GetCompileDefinitions().c_str());
|
||||
clOptions.AddDefines(this->GeneratorTarget->GetCompileDefinitions(
|
||||
this->Target->GetCompileDefinitions().c_str());
|
||||
clOptions.AddDefines(this->Target->GetCompileDefinitions(
|
||||
configName.c_str()).c_str());
|
||||
clOptions.SetVerboseMakefile(
|
||||
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
|
||||
|
|
|
@ -3302,6 +3302,12 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
|
|||
int result = 0;
|
||||
while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
|
||||
{
|
||||
// Skip empty command lines.
|
||||
if(command.find_first_not_of(" \t") == command.npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Setup this command line.
|
||||
const char* cmd[2] = {command.c_str(), 0};
|
||||
cmsysProcess_SetCommand(cp, cmd);
|
||||
|
@ -3555,6 +3561,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
|
|||
chained);
|
||||
}
|
||||
|
||||
bool cmake::GetIsPropertyDefined(const char *name,
|
||||
cmProperty::ScopeType scope)
|
||||
{
|
||||
return this->PropertyDefinitions[scope].find(name) !=
|
||||
this->PropertyDefinitions[scope].end();
|
||||
}
|
||||
|
||||
cmPropertyDefinition *cmake
|
||||
::GetPropertyDefinition(const char *name,
|
||||
cmProperty::ScopeType scope)
|
||||
|
@ -4384,6 +4397,10 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
|
|||
isError = true;
|
||||
msg << "CMake Internal Error (please report a bug)";
|
||||
}
|
||||
else if(t == cmake::LOG)
|
||||
{
|
||||
msg << "CMake Debug Log";
|
||||
}
|
||||
else
|
||||
{
|
||||
msg << "CMake Warning";
|
||||
|
|
|
@ -341,6 +341,8 @@ class cmake
|
|||
bool chain = false,
|
||||
const char *variableGroup = 0);
|
||||
|
||||
bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
|
||||
|
||||
// get property definition
|
||||
cmPropertyDefinition *GetPropertyDefinition
|
||||
(const char *name, cmProperty::ScopeType scope);
|
||||
|
|
|
@ -574,6 +574,8 @@ IF(KWSYS_USE_SystemTools)
|
|||
ENDIF()
|
||||
|
||||
IF(KWSYS_USE_SystemInformation)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
|
||||
IF(NOT CYGWIN)
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
|
||||
|
@ -603,6 +605,13 @@ IF(KWSYS_USE_SystemInformation)
|
|||
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(CMAKE_SYSTEM MATCHES "BSD")
|
||||
CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
|
||||
IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE)
|
||||
SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1)
|
||||
ENDIF()
|
||||
|
@ -631,6 +640,20 @@ IF(KWSYS_USE_SystemInformation)
|
|||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
|
||||
ENDIF()
|
||||
IF(BORLAND)
|
||||
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
|
||||
"Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
|
||||
IF(KWSYS_CXX_HAS_BORLAND_ASM)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
|
||||
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
|
||||
"Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
|
||||
IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(KWSYS_USE___INT64)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
|
||||
|
|
|
@ -418,9 +418,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
|
|||
parse it. */
|
||||
newCommands[cp->NumberOfCommands] =
|
||||
kwsysSystem_Parse_CommandForUnix(*command, 0);
|
||||
if(!newCommands[cp->NumberOfCommands])
|
||||
if(!newCommands[cp->NumberOfCommands] ||
|
||||
!newCommands[cp->NumberOfCommands][0])
|
||||
{
|
||||
/* Out of memory. */
|
||||
/* Out of memory or no command parsed. */
|
||||
free(newCommands);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,10 @@ typedef int siginfo_t;
|
|||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(KWSYS_SYS_HAS_MACHINE_CPU_H)
|
||||
# include <machine/cpu.h>
|
||||
#endif
|
||||
|
||||
#if defined(__DragonFly__)
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
@ -198,7 +202,7 @@ typedef struct rlimit ResourceLimitType;
|
|||
#define USE_CPUID_INTRINSICS 0
|
||||
#endif
|
||||
|
||||
#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS
|
||||
#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS || defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
|
||||
# define USE_CPUID 1
|
||||
#else
|
||||
# define USE_CPUID 0
|
||||
|
@ -220,6 +224,7 @@ static bool call_cpuid(int select, int result[4])
|
|||
return true;
|
||||
#else
|
||||
int tmp[4];
|
||||
#if defined(_MSC_VER)
|
||||
// Use SEH to determine CPUID presence
|
||||
__try {
|
||||
_asm {
|
||||
|
@ -258,7 +263,24 @@ static bool call_cpuid(int select, int result[4])
|
|||
return false;
|
||||
}
|
||||
|
||||
memcpy(result, tmp, sizeof(tmp));
|
||||
memcpy(result, tmp, sizeof(tmp));
|
||||
#elif defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
|
||||
unsigned int a, b, c, d;
|
||||
__asm {
|
||||
mov EAX, select;
|
||||
cpuid
|
||||
mov a, EAX;
|
||||
mov b, EBX;
|
||||
mov c, ECX;
|
||||
mov d, EDX;
|
||||
}
|
||||
|
||||
result[0] = a;
|
||||
result[1] = b;
|
||||
result[2] = c;
|
||||
result[3] = d;
|
||||
#endif
|
||||
|
||||
// The cpuid instruction succeeded.
|
||||
return true;
|
||||
#endif
|
||||
|
@ -428,7 +450,7 @@ protected:
|
|||
int CPUCount();
|
||||
unsigned char LogicalCPUPerPhysicalCPU();
|
||||
unsigned char GetAPICId();
|
||||
unsigned int IsHyperThreadingSupported();
|
||||
bool IsHyperThreadingSupported();
|
||||
static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int);
|
||||
|
||||
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
|
||||
|
@ -452,7 +474,8 @@ protected:
|
|||
kwsys_stl::string SysCtlBuffer;
|
||||
|
||||
// For Solaris
|
||||
bool QuerySolarisInfo();
|
||||
bool QuerySolarisMemory();
|
||||
bool QuerySolarisProcessor();
|
||||
kwsys_stl::string ParseValueFromKStat(const char* arguments);
|
||||
kwsys_stl::string RunProcess(kwsys_stl::vector<const char*> args);
|
||||
|
||||
|
@ -477,9 +500,11 @@ protected:
|
|||
//For AIX
|
||||
bool QueryAIXMemory();
|
||||
|
||||
bool QueryProcessorBySysconf();
|
||||
bool QueryProcessor();
|
||||
|
||||
// Evaluate the memory information.
|
||||
bool QueryMemoryBySysconf();
|
||||
bool QueryMemory();
|
||||
size_t TotalVirtualMemory;
|
||||
size_t AvailableVirtualMemory;
|
||||
|
@ -1283,7 +1308,7 @@ void SystemInformationImplementation::RunCPUCheck()
|
|||
#elif defined(__APPLE__)
|
||||
this->ParseSysCtl();
|
||||
#elif defined (__SVR4) && defined (__sun)
|
||||
this->QuerySolarisInfo();
|
||||
this->QuerySolarisProcessor();
|
||||
#elif defined(__HAIKU__)
|
||||
this->QueryHaikuInfo();
|
||||
#elif defined(__QNX__)
|
||||
|
@ -1309,7 +1334,7 @@ void SystemInformationImplementation::RunMemoryCheck()
|
|||
#if defined(__APPLE__)
|
||||
this->ParseSysCtl();
|
||||
#elif defined (__SVR4) && defined (__sun)
|
||||
this->QuerySolarisInfo();
|
||||
this->QuerySolarisMemory();
|
||||
#elif defined(__HAIKU__)
|
||||
this->QueryHaikuInfo();
|
||||
#elif defined(__QNX__)
|
||||
|
@ -3012,7 +3037,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SystemInformationImplementation::QueryProcessor()
|
||||
bool SystemInformationImplementation::QueryProcessorBySysconf()
|
||||
{
|
||||
#if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN)
|
||||
// IRIX names this slightly different
|
||||
|
@ -3026,7 +3051,7 @@ bool SystemInformationImplementation::QueryProcessor()
|
|||
return false;
|
||||
}
|
||||
|
||||
this->NumberOfPhysicalCPU = c;
|
||||
this->NumberOfPhysicalCPU = static_cast<unsigned int>(c);
|
||||
this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
|
||||
|
||||
return true;
|
||||
|
@ -3035,6 +3060,11 @@ bool SystemInformationImplementation::QueryProcessor()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool SystemInformationImplementation::QueryProcessor()
|
||||
{
|
||||
return this->QueryProcessorBySysconf();
|
||||
}
|
||||
|
||||
/**
|
||||
Get total system RAM in units of KiB.
|
||||
*/
|
||||
|
@ -3555,8 +3585,7 @@ bool SystemInformationImplementation::QueryAIXMemory()
|
|||
#endif
|
||||
}
|
||||
|
||||
/** Query for the memory status */
|
||||
bool SystemInformationImplementation::QueryMemory()
|
||||
bool SystemInformationImplementation::QueryMemoryBySysconf()
|
||||
{
|
||||
#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
|
||||
// Assume the mmap() granularity as returned by _SC_PAGESIZE is also
|
||||
|
@ -3593,6 +3622,12 @@ bool SystemInformationImplementation::QueryMemory()
|
|||
#endif
|
||||
}
|
||||
|
||||
/** Query for the memory status */
|
||||
bool SystemInformationImplementation::QueryMemory()
|
||||
{
|
||||
return this->QueryMemoryBySysconf();
|
||||
}
|
||||
|
||||
/** */
|
||||
size_t SystemInformationImplementation::GetTotalVirtualMemory()
|
||||
{
|
||||
|
@ -3725,8 +3760,13 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
|
|||
|
||||
|
||||
/** Works only for windows */
|
||||
unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
|
||||
bool SystemInformationImplementation::IsHyperThreadingSupported()
|
||||
{
|
||||
if (this->Features.ExtendedFeatures.SupportsHyperthreading)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if USE_CPUID
|
||||
int Regs[4] = { 0, 0, 0, 0 },
|
||||
VendorId[4] = { 0, 0, 0, 0 };
|
||||
|
@ -3744,13 +3784,15 @@ unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
|
|||
|
||||
if (((Regs[0] & FAMILY_ID) == PENTIUM4_ID) || (Regs[0] & EXT_FAMILY_ID))
|
||||
{
|
||||
if (VendorId[1] == 'uneG')
|
||||
if (VendorId[1] == 0x756e6547) // 'uneG'
|
||||
{
|
||||
if (VendorId[3] == 'Ieni')
|
||||
if (VendorId[3] == 0x49656e69) // 'Ieni'
|
||||
{
|
||||
if (VendorId[2] == 'letn')
|
||||
if (VendorId[2] == 0x6c65746e) // 'letn'
|
||||
{
|
||||
return(Regs[3] & HT_BIT); // Genuine Intel with hyper-Threading technology
|
||||
// Genuine Intel with hyper-Threading technology
|
||||
this->Features.ExtendedFeatures.SupportsHyperthreading = ((Regs[3] & HT_BIT) != 0);
|
||||
return this->Features.ExtendedFeatures.SupportsHyperthreading;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4000,6 +4042,81 @@ bool SystemInformationImplementation::ParseSysCtl()
|
|||
len = sizeof(value);
|
||||
err = sysctlbyname("machdep.cpu.model", &value, &len, NULL, 0);
|
||||
this->ChipID.Model = static_cast< int >( value );
|
||||
|
||||
// Chip Stepping
|
||||
len = sizeof(value);
|
||||
value = 0;
|
||||
err = sysctlbyname("machdep.cpu.stepping", &value, &len, NULL, 0);
|
||||
if (!err)
|
||||
{
|
||||
this->ChipID.Revision = static_cast< int >( value );
|
||||
}
|
||||
|
||||
// feature string
|
||||
char *buf = 0;
|
||||
size_t allocSize = 128;
|
||||
|
||||
err = 0;
|
||||
len = 0;
|
||||
|
||||
// sysctlbyname() will return with err==0 && len==0 if the buffer is too small
|
||||
while (err == 0 && len == 0)
|
||||
{
|
||||
delete[] buf;
|
||||
allocSize *= 2;
|
||||
buf = new char[allocSize];
|
||||
if (!buf)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buf[0] = ' ';
|
||||
len = allocSize - 2; // keep space for leading and trailing space
|
||||
err = sysctlbyname("machdep.cpu.features", buf + 1, &len, NULL, 0);
|
||||
}
|
||||
if (!err && buf && len)
|
||||
{
|
||||
// now we can match every flags as space + flag + space
|
||||
buf[len + 1] = ' ';
|
||||
kwsys_stl::string cpuflags(buf, len + 2);
|
||||
|
||||
if ((cpuflags.find(" FPU ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasFPU = true;
|
||||
}
|
||||
if ((cpuflags.find(" TSC ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasTSC = true;
|
||||
}
|
||||
if ((cpuflags.find(" MMX ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasMMX = true;
|
||||
}
|
||||
if ((cpuflags.find(" SSE ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasSSE = true;
|
||||
}
|
||||
if ((cpuflags.find(" SSE2 ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasSSE2 = true;
|
||||
}
|
||||
if ((cpuflags.find(" APIC ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasAPIC = true;
|
||||
}
|
||||
if ((cpuflags.find(" CMOV ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasCMOV = true;
|
||||
}
|
||||
if ((cpuflags.find(" MTRR ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasMTRR = true;
|
||||
}
|
||||
if ((cpuflags.find(" ACPI ")!=kwsys_stl::string::npos))
|
||||
{
|
||||
this->Features.HasACPI = true;
|
||||
}
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
// brand string
|
||||
|
@ -4059,13 +4176,12 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
|
|||
char* data = NULL;
|
||||
int length;
|
||||
double timeout = 255;
|
||||
int pipe; // pipe id as returned by kwsysProcess_WaitForData()
|
||||
|
||||
while(kwsysProcess_WaitForData(gp,&data,&length,&timeout)) // wait for 1s
|
||||
while( ( pipe = kwsysProcess_WaitForData(gp,&data,&length,&timeout),
|
||||
(pipe == kwsysProcess_Pipe_STDOUT || pipe == kwsysProcess_Pipe_STDERR) ) ) // wait for 1s
|
||||
{
|
||||
for(int i=0;i<length;i++)
|
||||
{
|
||||
buffer += data[i];
|
||||
}
|
||||
buffer.append(data, length);
|
||||
}
|
||||
kwsysProcess_WaitForExit(gp, 0);
|
||||
|
||||
|
@ -4173,16 +4289,40 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
/** Querying for system information from Solaris */
|
||||
bool SystemInformationImplementation::QuerySolarisInfo()
|
||||
bool SystemInformationImplementation::QuerySolarisMemory()
|
||||
{
|
||||
// Parse values
|
||||
this->NumberOfPhysicalCPU = static_cast<unsigned int>(
|
||||
atoi(this->ParseValueFromKStat("-n syste_misc -s ncpus").c_str()));
|
||||
this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
|
||||
this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = 1;
|
||||
#if defined (__SVR4) && defined (__sun)
|
||||
// Solaris allows querying this value by sysconf, but if this is
|
||||
// a 32 bit process on a 64 bit host the returned memory will be
|
||||
// limited to 4GiB. So if this is a 32 bit process or if the sysconf
|
||||
// method fails use the kstat interface.
|
||||
#if SIZEOF_VOID_P == 8
|
||||
if (this->QueryMemoryBySysconf())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* tail;
|
||||
unsigned long totalMemory =
|
||||
strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
|
||||
this->TotalPhysicalMemory = totalMemory/128;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemInformationImplementation::QuerySolarisProcessor()
|
||||
{
|
||||
if (!this->QueryProcessorBySysconf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse values
|
||||
this->CPUSpeedInMHz = static_cast<float>(atoi(this->ParseValueFromKStat("-s clock_MHz").c_str()));
|
||||
|
||||
// Chip family
|
||||
|
@ -4199,20 +4339,6 @@ bool SystemInformationImplementation::QuerySolarisInfo()
|
|||
this->FindManufacturer();
|
||||
}
|
||||
|
||||
// Cache size
|
||||
this->Features.L1CacheSize = 0;
|
||||
this->Features.L2CacheSize = 0;
|
||||
|
||||
char* tail;
|
||||
unsigned long totalMemory =
|
||||
strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
|
||||
this->TotalPhysicalMemory = totalMemory/128;
|
||||
|
||||
// Undefined values (for now at least)
|
||||
this->TotalVirtualMemory = 0;
|
||||
this->AvailablePhysicalMemory = 0;
|
||||
this->AvailableVirtualMemory = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4424,6 +4550,45 @@ bool SystemInformationImplementation::QueryBSDProcessor()
|
|||
this->CPUSpeedInMHz = (float) k;
|
||||
#endif
|
||||
|
||||
#if defined(CPU_SSE)
|
||||
ctrl[0] = CTL_MACHDEP;
|
||||
ctrl[1] = CPU_SSE;
|
||||
|
||||
if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->Features.HasSSE = (k > 0);
|
||||
#endif
|
||||
|
||||
#if defined(CPU_SSE2)
|
||||
ctrl[0] = CTL_MACHDEP;
|
||||
ctrl[1] = CPU_SSE2;
|
||||
|
||||
if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->Features.HasSSE2 = (k > 0);
|
||||
#endif
|
||||
|
||||
#if defined(CPU_CPUVENDOR)
|
||||
ctrl[0] = CTL_MACHDEP;
|
||||
ctrl[1] = CPU_CPUVENDOR;
|
||||
char vbuf[25];
|
||||
::memset(vbuf, 0, sizeof(vbuf));
|
||||
sz = sizeof(vbuf) - 1;
|
||||
if (sysctl(ctrl, 2, vbuf, &sz, NULL, 0) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->ChipID.Vendor = vbuf;
|
||||
this->FindManufacturer();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
|
|
|
@ -580,3 +580,30 @@ int main()
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
|
||||
int main()
|
||||
{
|
||||
int a = 1;
|
||||
__asm {
|
||||
xor EBX, EBX;
|
||||
mov a, EBX;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID
|
||||
int main()
|
||||
{
|
||||
int a = 0;
|
||||
__asm {
|
||||
xor EAX, EAX;
|
||||
cpuid;
|
||||
mov a, EAX;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,15 +12,12 @@ target_compile_definitions(target_compile_definitions
|
|||
INTERFACE MY_INTERFACE_DEFINE
|
||||
)
|
||||
|
||||
add_library(importedlib UNKNOWN IMPORTED)
|
||||
target_compile_definitions(importedlib
|
||||
INTERFACE MY_IMPORTEDINTERFACE_DEFINE
|
||||
)
|
||||
|
||||
add_executable(consumer
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
|
||||
)
|
||||
|
||||
target_compile_definitions(consumer
|
||||
PRIVATE target_compile_definitions importedlib
|
||||
$<$<TARGET_DEFINED:notdefined>:SHOULD_NOT_BE_DEFINED>
|
||||
$<$<TARGET_DEFINED:target_compile_definitions>:SHOULD_BE_DEFINED>
|
||||
)
|
||||
|
|
|
@ -11,8 +11,12 @@
|
|||
#error Expected MY_INTERFACE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef MY_IMPORTEDINTERFACE_DEFINE
|
||||
#error Expected MY_IMPORTEDINTERFACE_DEFINE
|
||||
#ifdef SHOULD_NOT_BE_DEFINED
|
||||
#error Unexpected SHOULD_NOT_BE_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef SHOULD_BE_DEFINED
|
||||
#error Expected SHOULD_BE_DEFINED
|
||||
#endif
|
||||
|
||||
int main() { return 0; }
|
||||
|
|
|
@ -11,9 +11,6 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/publicinclude/publicinclude.h" "#define
|
|||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude/interfaceinclude.h" "#define INTERFACEINCLUDE_DEFINE\n")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude/importedinterfaceinclude.h" "#define IMPORTEDINTERFACEINCLUDE_DEFINE\n")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/poison")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/poison/common.h" "#error Should not be included\n")
|
||||
|
||||
|
@ -33,12 +30,12 @@ target_include_directories(target_include_directories
|
|||
PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/poison"
|
||||
)
|
||||
target_include_directories(target_include_directories
|
||||
BEFORE PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/cure"
|
||||
BEFORE PUBLIC "$<$<TARGET_DEFINED:target_include_directories>:${CMAKE_CURRENT_BINARY_DIR}/cure>"
|
||||
)
|
||||
|
||||
add_library(importedlib UNKNOWN IMPORTED)
|
||||
target_include_directories(importedlib
|
||||
INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude"
|
||||
# Has no effect because the target is not defined:
|
||||
target_include_directories(target_include_directories
|
||||
BEFORE PUBLIC "$<$<TARGET_DEFINED:notdefined>:${CMAKE_CURRENT_BINARY_DIR}/poison>"
|
||||
)
|
||||
|
||||
add_executable(consumer
|
||||
|
@ -46,5 +43,5 @@ add_executable(consumer
|
|||
)
|
||||
|
||||
target_include_directories(consumer
|
||||
PRIVATE target_include_directories importedlib
|
||||
PRIVATE target_include_directories
|
||||
)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "common.h"
|
||||
#include "publicinclude.h"
|
||||
#include "interfaceinclude.h"
|
||||
#include "importedinterfaceinclude.h"
|
||||
|
||||
#ifdef PRIVATEINCLUDE_DEFINE
|
||||
#error Unexpected PRIVATEINCLUDE_DEFINE
|
||||
|
@ -16,10 +15,6 @@
|
|||
#error Expected INTERFACEINCLUDE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef IMPORTEDINTERFACEINCLUDE_DEFINE
|
||||
#error Expected IMPORTEDINTERFACEINCLUDE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef CURE_DEFINE
|
||||
#error Expected CURE_DEFINE
|
||||
#endif
|
||||
|
|
|
@ -29,9 +29,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||
add_library(depA SHARED depA.cpp)
|
||||
generate_export_header(depA)
|
||||
|
||||
add_library(importedlib UNKNOWN IMPORTED)
|
||||
target_link_libraries(importedlib LINK_INTERFACE_LIBRARIES depA)
|
||||
|
||||
add_library(depB SHARED depB.cpp)
|
||||
generate_export_header(depB)
|
||||
|
||||
|
@ -80,3 +77,13 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "")
|
|||
add_library(depIfaceOnly SHARED EXCLUDE_FROM_ALL depIfaceOnly.cpp)
|
||||
generate_export_header(depIfaceOnly)
|
||||
set_property(TARGET depB APPEND PROPERTY LINK_INTERFACE_LIBRARIES depIfaceOnly)
|
||||
|
||||
add_library(depD SHARED depD.cpp)
|
||||
generate_export_header(depD)
|
||||
set_property(TARGET depD APPEND PROPERTY
|
||||
LINK_INTERFACE_LIBRARIES
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depA>
|
||||
)
|
||||
|
||||
add_executable(targetB targetB.cpp)
|
||||
target_link_libraries(targetB depD)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#include "depD.h"
|
||||
|
||||
int DepD::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DepA DepD::getA()
|
||||
{
|
||||
DepA a;
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
#include "depd_export.h"
|
||||
|
||||
#include "depA.h"
|
||||
|
||||
struct DEPD_EXPORT DepD
|
||||
{
|
||||
int foo();
|
||||
|
||||
DepA getA();
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#include "depD.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DepD d;
|
||||
DepA a = d.getA();
|
||||
|
||||
return d.foo() + a.foo();
|
||||
}
|
|
@ -216,6 +216,7 @@ if(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(PolicyScope PolicyScope)
|
||||
ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
|
||||
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
|
||||
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
||||
set_tests_properties(EmptyLibrary PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
|
||||
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
||||
|
|
|
@ -4,7 +4,8 @@ set(CMAKE_EXECUTABLE "${CMake_BIN_DIR}/cmake")
|
|||
macro(AddCMakeTest TestName PreArgs)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TestName}Test.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" @ONLY IMMEDIATE)
|
||||
add_test(CMake.${TestName} ${CMAKE_EXECUTABLE} ${PreArgs}
|
||||
add_test(NAME CMake.${TestName}
|
||||
COMMAND ${CMAKE_EXECUTABLE} ${PreArgs}
|
||||
-P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN})
|
||||
endmacro()
|
||||
|
||||
|
@ -28,7 +29,7 @@ AddCMakeTest(String "")
|
|||
AddCMakeTest(Math "")
|
||||
AddCMakeTest(CMakeMinimumRequired "")
|
||||
AddCMakeTest(CompilerIdVendor "")
|
||||
AddCMakeTest(ProcessorCount "")
|
||||
AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>")
|
||||
AddCMakeTest(PushCheckState "")
|
||||
AddCMakeTest(While "")
|
||||
|
||||
|
|
|
@ -9,10 +9,17 @@ message("### 3. ProcessorCount(...) function call is emitting output that it sho
|
|||
message("processor_count='${processor_count}'")
|
||||
|
||||
execute_process(
|
||||
COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx"
|
||||
COMMAND "${KWSYS_TEST_EXE}"
|
||||
testSystemInformation
|
||||
OUTPUT_VARIABLE tsi_out
|
||||
ERROR_VARIABLE tsi_err)
|
||||
ERROR_VARIABLE tsi_err
|
||||
RESULT_VARIABLE tsi_res
|
||||
)
|
||||
if (tsi_res)
|
||||
message("executing \"${KWSYS_TEST_EXE}\" failed")
|
||||
message(FATAL_ERROR "output: ${tsi_res}")
|
||||
endif ()
|
||||
|
||||
string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2"
|
||||
system_info_processor_count "${tsi_out}")
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(CompatibleInterface)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_library(iface1 empty.cpp)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_BOOL
|
||||
BOOL_PROP1
|
||||
BOOL_PROP2
|
||||
BOOL_PROP3
|
||||
BOOL_PROP4
|
||||
)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING
|
||||
STRING_PROP1
|
||||
STRING_PROP2
|
||||
STRING_PROP3
|
||||
)
|
||||
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
|
||||
|
||||
add_executable(CompatibleInterface main.cpp)
|
||||
target_link_libraries(CompatibleInterface iface1)
|
||||
|
||||
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
|
||||
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
|
||||
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
|
||||
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
|
||||
|
||||
target_compile_definitions(CompatibleInterface
|
||||
PRIVATE
|
||||
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
|
||||
)
|
||||
|
||||
|
||||
add_library(iface2 SHARED iface2.cpp)
|
||||
generate_export_header(iface2)
|
||||
|
||||
# For the LINK_LIBRARIES and related properties, we should not evaluate
|
||||
# properties defined only in the interface - they should be implicitly zero
|
||||
set_property(TARGET iface2
|
||||
APPEND PROPERTY
|
||||
LINK_INTERFACE_LIBRARIES $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP4>>:nonexistant>
|
||||
)
|
||||
target_link_libraries(CompatibleInterface iface2)
|
|
@ -0,0 +1 @@
|
|||
// no content
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "iface2.h"
|
||||
|
||||
int Iface2::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#ifndef IFACE2_H
|
||||
#define IFACE2_H
|
||||
|
||||
#include "iface2_export.h"
|
||||
|
||||
class IFACE2_EXPORT Iface2
|
||||
{
|
||||
public:
|
||||
int foo();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#ifndef BOOL_PROP1
|
||||
#error Expected BOOL_PROP1
|
||||
#endif
|
||||
|
||||
#ifndef BOOL_PROP2
|
||||
#error Expected BOOL_PROP2
|
||||
#endif
|
||||
|
||||
#ifndef BOOL_PROP3
|
||||
#error Expected BOOL_PROP3
|
||||
#endif
|
||||
|
||||
#ifndef STRING_PROP1
|
||||
#error Expected STRING_PROP1
|
||||
#endif
|
||||
|
||||
#ifndef STRING_PROP2
|
||||
#error Expected STRING_PROP2
|
||||
#endif
|
||||
|
||||
#ifndef STRING_PROP3
|
||||
#error Expected STRING_PROP3
|
||||
#endif
|
||||
|
||||
#include "iface2.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Iface2 if2;
|
||||
return if2.foo();
|
||||
}
|
|
@ -158,6 +158,56 @@ set_property(TARGET testLibRequired APPEND PROPERTY
|
|||
$<INSTALL_INTERFACE:InstallOnly_DEFINE>
|
||||
)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
|
||||
add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
|
||||
generate_export_header(testSharedLibRequired)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
PROPERTY
|
||||
INTERFACE_POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
PROPERTY
|
||||
INTERFACE_CUSTOM_PROP ON
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING CUSTOM_STRING
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
PROPERTY
|
||||
INTERFACE_CUSTOM_STRING testcontent
|
||||
)
|
||||
|
||||
add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
|
||||
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
generate_export_header(testSharedLibDepends)
|
||||
|
||||
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:testSharedLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||
LINK_INTERFACE_LIBRARIES
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
|
||||
)
|
||||
|
||||
# LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above.
|
||||
target_link_libraries(testSharedLibDepends LINK_PRIVATE testSharedLibRequired)
|
||||
|
||||
install(TARGETS testLibRequired
|
||||
testLibIncludeRequired1
|
||||
testLibIncludeRequired2
|
||||
|
@ -165,10 +215,11 @@ install(TARGETS testLibRequired
|
|||
testLibIncludeRequired4
|
||||
testLibIncludeRequired5
|
||||
testLibIncludeRequired6
|
||||
testSharedLibRequired
|
||||
EXPORT RequiredExp DESTINATION lib )
|
||||
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired)
|
||||
|
||||
install(TARGETS testLibDepends EXPORT DependsExp DESTINATION lib )
|
||||
install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
|
||||
install(EXPORT DependsExp FILE testLibDependsConfig.cmake DESTINATION lib/cmake/testLibDepends)
|
||||
|
||||
|
||||
|
@ -216,9 +267,12 @@ if(WIN32)
|
|||
install(TARGETS testLib5 RUNTIME DESTINATION bin)
|
||||
endif()
|
||||
|
||||
add_subdirectory(sublib) # For CMAKE_BUILD_INTERFACE_INCLUDES test.
|
||||
|
||||
# Export from build tree.
|
||||
export(TARGETS testExe1 testLib1 testLib2 testLib3
|
||||
testExe2libImp testLib3Imp testLib3ImpDep
|
||||
testExe2libImp testLib3Imp testLib3ImpDep subdirlib
|
||||
testSharedLibRequired testSharedLibDepends
|
||||
NAMESPACE bld_
|
||||
FILE ExportBuildTree.cmake
|
||||
)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_library(subdirlib SHARED subdir.cpp)
|
||||
generate_export_header(subdirlib)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "subdir.h"
|
||||
|
||||
int SubDirObject::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef SUBDIR_H
|
||||
#define SUBDIR_H
|
||||
|
||||
#include "subdirlib_export.h"
|
||||
|
||||
struct SUBDIRLIB_EXPORT SubDirObject
|
||||
{
|
||||
int foo();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#include "testSharedLibDepends.h"
|
||||
|
||||
int TestSharedLibDepends::foo()
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#ifndef TESTSHAREDLIBDEPENDS_H
|
||||
#define TESTSHAREDLIBDEPENDS_H
|
||||
|
||||
#include "testsharedlibdepends_export.h"
|
||||
|
||||
#include "testSharedLibRequired.h"
|
||||
|
||||
struct TESTSHAREDLIBDEPENDS_EXPORT TestSharedLibDepends
|
||||
{
|
||||
int foo();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "testSharedLibRequired.h"
|
||||
|
||||
int TestSharedLibRequired::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef TESTSHAREDLIBREQUIRED_H
|
||||
#define TESTSHAREDLIBREQUIRED_H
|
||||
|
||||
#include "testsharedlibrequired_export.h"
|
||||
|
||||
struct TESTSHAREDLIBREQUIRED_EXPORT TestSharedLibRequired
|
||||
{
|
||||
int foo();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -157,13 +157,50 @@ endif()
|
|||
# Test that dependent imported targets have usable
|
||||
# INTERFACE_COMPILE_DEFINITIONS and INTERFACE_INCLUDE_DIRECTORIES
|
||||
|
||||
add_library(deps_iface deps_iface.cpp)
|
||||
target_link_libraries(deps_iface testLibsDepends)
|
||||
set_property(TARGET deps_iface APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:testLibDepends,INTERFACE_COMPILE_DEFINITIONS>
|
||||
add_executable(deps_iface deps_iface.c)
|
||||
target_link_libraries(deps_iface testLibDepends)
|
||||
target_include_directories(deps_iface PRIVATE testLibDepends)
|
||||
target_compile_definitions(deps_iface PRIVATE testLibDepends)
|
||||
|
||||
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
||||
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
||||
target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
|
||||
target_compile_definitions(deps_shared_iface
|
||||
PRIVATE
|
||||
testSharedLibDepends
|
||||
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
|
||||
)
|
||||
set_property(TARGET deps_iface APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:testLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
|
||||
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag(-fPIE run_pic_test)
|
||||
else()
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "PGI"
|
||||
OR CMAKE_CXX_COMPILER_ID MATCHES "PathScale"
|
||||
OR CMAKE_SYSTEM_NAME MATCHES "IRIX64"
|
||||
OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||
set(run_pic_test 0)
|
||||
else()
|
||||
set(run_pic_test 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (run_pic_test)
|
||||
target_compile_definitions(deps_shared_iface PRIVATE CHECK_PIC_WORKS)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test that targets imported from the build tree have their dependencies
|
||||
# evaluated correctly. The above already tests the same for the install tree.
|
||||
|
||||
add_executable(deps_shared_iface2 deps_shared_iface.cpp)
|
||||
target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
|
||||
target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
|
||||
target_compile_definitions(deps_shared_iface2
|
||||
PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
|
||||
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
|
||||
)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
extern int testLibDepends(void);
|
||||
|
||||
|
||||
int main(int,char **)
|
||||
int main()
|
||||
{
|
||||
return testLibDepends();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
|
||||
#include "testSharedLibDepends.h"
|
||||
|
||||
#ifdef CHECK_PIC_WORKS
|
||||
#if defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__)
|
||||
#error Expected by INTERFACE_POSITION_INDEPENDENT_CODE property of dependency
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PIC_PROPERTY_IS_ON
|
||||
#error Expected PIC_PROPERTY_IS_ON
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_PROPERTY_IS_ON
|
||||
#error Expected CUSTOM_PROPERTY_IS_ON
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_STRING_IS_MATCH
|
||||
#error Expected CUSTOM_STRING_IS_MATCH
|
||||
#endif
|
||||
|
||||
#ifdef TEST_SUBDIR_LIB
|
||||
#include "subdir.h"
|
||||
#endif
|
||||
|
||||
int main(int,char **)
|
||||
{
|
||||
TestSharedLibDepends dep;
|
||||
TestSharedLibRequired req;
|
||||
|
||||
#ifdef TEST_SUBDIR_LIB
|
||||
SubDirObject sdo;
|
||||
#endif
|
||||
|
||||
return dep.foo() + req.foo()
|
||||
#ifdef TEST_SUBDIR_LIB
|
||||
+ sdo.foo()
|
||||
#endif
|
||||
;
|
||||
}
|
|
@ -50,6 +50,8 @@ if(NOT DEFINED can_build_tutorial_step5)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(NonExternalProjectTarget
|
||||
COMMAND ${CMAKE_COMMAND} -E echo NonExternalProjectTarget)
|
||||
|
||||
# Empty projects that test all the known ExternalProject_Add argument key words:
|
||||
#
|
||||
|
@ -94,7 +96,7 @@ ExternalProject_Add(${proj}
|
|||
CVS_REPOSITORY ""
|
||||
CVS_MODULE ""
|
||||
CVS_TAG ""
|
||||
DEPENDS "MinimalNoOpProject"
|
||||
DEPENDS "MinimalNoOpProject" NonExternalProjectTarget
|
||||
DOWNLOAD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
|
|
|
@ -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"
|
|
@ -13,11 +13,14 @@ add_definitions(-DFOO -DSomeDefine="Barx")
|
|||
# enable relaxed mode so automoc can handle all the special cases:
|
||||
set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
|
||||
|
||||
# create an executable and a library target, both requiring automoc:
|
||||
# create an executable and two library targets, each requiring automoc:
|
||||
add_library(codeeditorLib STATIC codeeditor.cpp)
|
||||
|
||||
add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp xyz.cpp yaf.cpp private_slot.cpp)
|
||||
add_library(privateSlot OBJECT private_slot.cpp)
|
||||
|
||||
set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE)
|
||||
add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
|
||||
xyz.cpp yaf.cpp $<TARGET_OBJECTS:privateSlot>)
|
||||
|
||||
set_target_properties(foo codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
|
||||
|
||||
target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} )
|
||||
|
|
|
@ -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)
|
|
@ -53,12 +53,14 @@ add_RunCMake_test(ObjectLibrary)
|
|||
if(NOT WIN32)
|
||||
add_RunCMake_test(PositionIndependentCode)
|
||||
endif()
|
||||
add_RunCMake_test(CompatibleInterface)
|
||||
|
||||
add_RunCMake_test(build_command)
|
||||
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)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} CXX)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
|
||||
COMPATIBLE_INTERFACE_BOOL property. This is not allowed. Only
|
||||
user-defined properties may appear listed in the COMPATIBLE_INTERFACE_BOOL
|
||||
property.
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
add_library(foo UNKNOWN IMPORTED)
|
||||
add_library(bar UNKNOWN IMPORTED)
|
||||
|
||||
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL INCLUDE_DIRECTORIES)
|
||||
set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
|
||||
set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
|
||||
|
||||
add_executable(user main.cpp)
|
||||
set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES OFF)
|
||||
target_link_libraries(user foo bar)
|
|
@ -0,0 +1 @@
|
|||
1
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue