Genex: Implement generator expressions for target PDB files.

This commit is contained in:
Nils Gladitz 2014-07-24 22:18:21 +02:00 committed by Brad King
parent 028ad31878
commit f86850ef60
14 changed files with 143 additions and 0 deletions

View File

@ -148,6 +148,17 @@ than 4.2.0.
Name of file with soname (.so.3).
``$<TARGET_SONAME_FILE_DIR:tgt>``
Directory of with soname (.so.3).
``$<TARGET_PDB_FILE:tgt>``
Full path to the linker generated program database file (.pdb)
where ``tgt`` is the name of a target.
See also the :prop_tgt:`PDB_NAME` and :prop_tgt:`PDB_OUTPUT_DIRECTORY`
target properties and their configuration specific variants
:prop_tgt:`PDB_NAME_<CONFIG>` and :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`.
``$<TARGET_PDB_FILE_NAME:tgt>``
Name of the linker generated program database file (.pdb).
``$<TARGET_PDB_FILE_DIR:tgt>``
Directory of the linker generated program database file (.pdb).
``$<TARGET_PROPERTY:tgt,prop>``
Value of the property ``prop`` on the target ``tgt``.

View File

@ -261,4 +261,5 @@ macro(__windows_compiler_msvc lang)
set(CMAKE_${lang}_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG")
set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON)
endmacro()

View File

@ -1512,6 +1512,7 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
class ArtifactNameTag;
class ArtifactLinkerTag;
class ArtifactSonameTag;
class ArtifactPdbTag;
class ArtifactPathTag;
class ArtifactDirTag;
@ -1556,6 +1557,44 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
}
};
//----------------------------------------------------------------------------
template<>
struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
{
static std::string Create(cmTarget* target,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content)
{
std::string language = target->GetLinkerLanguage(context->Config);
std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
if(!context->Makefile->IsOn(pdbSupportVar))
{
::reportError(context, content->GetOriginalExpression(),
"TARGET_PDB_FILE is not supported by the target linker.");
return std::string();
}
cmTarget::TargetType targetType = target->GetType();
if(targetType != cmTarget::SHARED_LIBRARY &&
targetType != cmTarget::MODULE_LIBRARY &&
targetType != cmTarget::EXECUTABLE)
{
::reportError(context, content->GetOriginalExpression(),
"TARGET_PDB_FILE is allowed only for "
"targets with linker created artifacts.");
return std::string();
}
std::string result = target->GetPDBDirectory(context->Config);
result += "/";
result += target->GetPDBName(context->Config);
return result;
}
};
//----------------------------------------------------------------------------
template<>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
@ -1706,6 +1745,9 @@ TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> targetLinkerNodeGroup;
static const
TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup;
static const
TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup;
//----------------------------------------------------------------------------
static const
cmGeneratorExpressionNode* GetNode(const std::string &identifier)
@ -1733,12 +1775,15 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
nodeMap["TARGET_FILE"] = &targetNodeGroup.File;
nodeMap["TARGET_LINKER_FILE"] = &targetLinkerNodeGroup.File;
nodeMap["TARGET_SONAME_FILE"] = &targetSoNameNodeGroup.File;
nodeMap["TARGET_PDB_FILE"] = &targetPdbNodeGroup.File;
nodeMap["TARGET_FILE_NAME"] = &targetNodeGroup.FileName;
nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerNodeGroup.FileName;
nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameNodeGroup.FileName;
nodeMap["TARGET_PDB_FILE_NAME"] = &targetPdbNodeGroup.FileName;
nodeMap["TARGET_FILE_DIR"] = &targetNodeGroup.FileDir;
nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir;
nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir;
nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir;
nodeMap["STREQUAL"] = &strEqualNode;
nodeMap["EQUAL"] = &equalNode;
nodeMap["LOWER_CASE"] = &lowerCaseNode;

View File

@ -21,6 +21,12 @@ if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 2)
set(File_Generate_ARGS -DXCODE_BELOW_2=1)
endif()
# Test MSVC for older host CMake versions, and test
# WIN32/CMAKE_C_COMPILER_ID to fix check on Intel for Windows.
if(MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel"))
set(GeneratorExpression_ARGS -DLINKER_SUPPORTS_PDB=1)
endif()
add_RunCMake_test(CMP0019)
add_RunCMake_test(CMP0022)
add_RunCMake_test(CMP0026)

View File

@ -0,0 +1,8 @@
CMake Error at NonValidCompiler-TARGET_PDB_FILE.cmake:6 \(file\):
Error evaluating generator expression:
\$<TARGET_PDB_FILE:empty>
TARGET_PDB_FILE is not supported by the target linker.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,9 @@
enable_language(C)
add_library(empty STATIC empty.c)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
CONTENT "[$<TARGET_PDB_FILE:empty>]"
)

View File

@ -0,0 +1,8 @@
CMake Error at NonValidTarget-TARGET_PDB_FILE.cmake:6 \(file\):
Error evaluating generator expression:
\$<TARGET_PDB_FILE:empty>
TARGET_PDB_FILE is allowed only for targets with linker created artifacts.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,9 @@
enable_language(C)
add_library(empty STATIC empty.c)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
CONTENT "[$<TARGET_PDB_FILE:empty>]"
)

View File

@ -16,3 +16,10 @@ run_cmake(NonValidTarget-C_COMPILER_VERSION)
run_cmake(NonValidTarget-CXX_COMPILER_VERSION)
run_cmake(NonValidTarget-TARGET_PROPERTY)
run_cmake(NonValidTarget-TARGET_POLICY)
if(LINKER_SUPPORTS_PDB)
run_cmake(NonValidTarget-TARGET_PDB_FILE)
run_cmake(ValidTarget-TARGET_PDB_FILE)
else()
run_cmake(NonValidCompiler-TARGET_PDB_FILE)
endif()

View File

@ -0,0 +1,17 @@
file(STRINGS ${RunCMake_TEST_BINARY_DIR}/test.txt TEST_TXT)
list(GET TEST_TXT 0 PDB_PATH)
list(GET TEST_TXT 1 PDB_NAME)
list(GET TEST_TXT 2 PDB_DIR)
if(NOT PDB_PATH MATCHES "empty\\.pdb")
message(FATAL_ERROR "unexpected PDB_PATH [${PDB_PATH}]")
endif()
if(NOT PDB_NAME STREQUAL "empty.pdb")
message(FATAL_ERROR "unexpected PDB_NAME [${PDB_NAME}]")
endif()
if(PDB_DIR MATCHES "empty\\.pdb")
message(FATAL_ERROR "unexpected PDB_DIR [${PDB_DIR}]")
endif()

View File

@ -0,0 +1,19 @@
enable_language(C)
add_library(empty SHARED empty.c)
if(CMAKE_CONFIGURATION_TYPES)
list(GET CMAKE_CONFIGURATION_TYPES 0 FIRST_CONFIG)
set(GENERATE_CONDITION CONDITION $<CONFIG:${FIRST_CONFIG}>)
endif()
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
CONTENT
[[$<TARGET_PDB_FILE:empty>
$<TARGET_PDB_FILE_NAME:empty>
$<TARGET_PDB_FILE_DIR:empty>
]]
${GENERATE_CONDITION}
)