PCH: Remove restrictions for REUSE_FROM signature for MSVC

Fixes: #20201
This commit is contained in:
Cristian Adam
2021-01-22 14:47:27 +01:00
committed by Brad King
parent 9e2e96f5ad
commit c450d66daa
5 changed files with 153 additions and 7 deletions

View File

@@ -2610,16 +2610,25 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
}
if (reuseTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) {
std::string pchSourceObj =
reuseTarget->GetPchFileObject(config, lang, arch);
// Link to the pch object file
std::string pchSourceObj =
reuseTarget->GetPchFileObject(config, lang, arch);
// Link to the pch object file
if (target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
std::string linkerProperty = "LINK_FLAGS_";
if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
linkerProperty = "STATIC_LIBRARY_FLAGS_";
}
target->Target->AppendProperty(
cmStrCat("LINK_FLAGS_", configUpper),
cmStrCat(linkerProperty, configUpper),
cmStrCat(" ",
this->ConvertToOutputFormat(pchSourceObj, SHELL)),
true);
} else {
target->Target->AppendProperty(
"INTERFACE_LINK_LIBRARIES",
cmStrCat("$<$<CONFIG:", config,
">:$<LINK_ONLY:", pchSourceObj, ">>"));
}
}
} else {
@@ -2738,7 +2747,7 @@ void cmLocalGenerator::CopyPchCompilePdb(
this->AddCustomCommandToTarget(
target->GetName(), outputs, no_deps, commandLines,
cmCustomCommandType::PRE_BUILD, no_message, no_current_dir, true, false,
"", "", false, cmObjectLibraryCommands::Reject, stdPipesUTF8);
"", "", false, cmObjectLibraryCommands::Accept, stdPipesUTF8);
} else {
cmImplicitDependsList no_implicit_depends;
cmSourceFile* copy_rule = this->AddCustomCommandToOutput(

View File

@@ -1010,7 +1010,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
this->GetStaticLibraryFlags(
libflags, configName, target->GetLinkerLanguage(configName), target);
if (!libflags.empty()) {
fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
fout << "\t\t\t\tAdditionalOptions=\"" << this->EscapeForXML(libflags)
<< "\"\n";
}
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";

View File

@@ -815,6 +815,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// avoiding a trailing backslash in the argument.
targetOutPathCompilePDB.back() = '/';
}
std::string compilePdbOutputPath =
this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(compilePdbOutputPath);
}
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();

View File

@@ -0,0 +1,131 @@
cmake_minimum_required(VERSION 3.18)
project(PchReuseFromObjLib)
set(CMAKE_PCH_WARN_INVALID OFF)
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
add_definitions(-DHAVE_PCH_SUPPORT)
endif()
######################################################################
file(WRITE ${CMAKE_BINARY_DIR}/CONFIG/config.hxx "/*empty*/\n")
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
void nothing()
{
}
]=])
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
#include <string.h>
namespace std {
struct string
{
char storage[20];
string(const char* s) {
strcpy(storage, s);
}
const char* c_str() const {
return storage;
}
};
}
]=])
add_library(pch-generator OBJECT ${CMAKE_BINARY_DIR}/pch.cxx)
set_property(TARGET pch-generator PROPERTY POSITION_INDEPENDENT_CODE ON)
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
target_include_directories(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
######################################################################
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
#include "message.hxx"
#ifndef HAVE_PCH_SUPPORT
#include "string.hxx"
#endif
const char* message()
{
static std::string greeting("hi there");
return greeting.c_str();
}
]=])
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
#include "config.hxx"
#ifdef WIN32_BUILD_SHARED
#ifdef BUILD_LIBRARY
#define MESSAGE_EXPORT __declspec(dllexport)
#else
#define MESSAGE_EXPORT __declspec(dllimport)
#endif
#else
#define MESSAGE_EXPORT
#endif
MESSAGE_EXPORT const char* message();
]=])
######################################################################
file(WRITE ${CMAKE_BINARY_DIR}/main.cxx [=[
#include "message.hxx"
#include <string.h>
int main()
{
return strcmp(message(), "hi there");
}
]=])
######################################################################
enable_testing()
function(add_library_and_executable type)
add_library(message_${type} ${type} ${CMAKE_BINARY_DIR}/message.cxx)
target_precompile_headers(message_${type} REUSE_FROM pch-generator)
set_property(TARGET message_${type} PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET message_${type} PROPERTY DEFINE_SYMBOL "")
if (WIN32 AND type STREQUAL "SHARED")
file(WRITE ${CMAKE_BINARY_DIR}/SHARED/config.hxx [=[
#define BUILD_LIBRARY
#define WIN32_BUILD_SHARED
]=])
target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/SHARED)
# Workaround for VS2008, the compiler fails with
# c1xx : fatal error C1083: Cannot open source file: '_WINDLL': No such file or directory
file(WRITE ${CMAKE_BINARY_DIR}/_WINDLL "/*empty*/\n")
else()
target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
endif()
add_executable(main_${type} ${CMAKE_BINARY_DIR}/main.cxx)
target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR})
if (WIN32 AND type STREQUAL "SHARED")
file(WRITE ${CMAKE_BINARY_DIR}/main_SHARED/config.hxx "#define WIN32_BUILD_SHARED\n")
target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR}/main_SHARED)
else()
target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
endif()
target_link_libraries(main_${type} PRIVATE message_${type})
add_test(NAME main_${type} COMMAND main_${type})
endfunction()
foreach(type OBJECT STATIC SHARED)
add_library_and_executable(${type})
endforeach()

View File

@@ -26,3 +26,4 @@ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
run_cmake(PchInstantiateTemplates)
endif()
endif()
run_test(PchReuseFromObjLib)