mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-10 15:50:50 -06:00
OBJECT libraries: Properly recognize if sources depend on configuration
Fixes: #21198
This commit is contained in:
@@ -1664,9 +1664,8 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
||||
if (context->EvaluateForBuildsystem) {
|
||||
// Use object file directory with buildsystem placeholder.
|
||||
obj_dir = gt->ObjectDirectory;
|
||||
// Here we assume that the set of object files produced
|
||||
// by an object library does not vary with configuration
|
||||
// and do not set HadContextSensitiveCondition to true.
|
||||
context->HadContextSensitiveCondition =
|
||||
gt->HasContextDependentSources();
|
||||
} else {
|
||||
// Use object file directory with per-config location.
|
||||
obj_dir = gt->GetObjectDirectory(context->Config);
|
||||
|
||||
@@ -276,8 +276,8 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
|
||||
, DebugLinkDirectoriesDone(false)
|
||||
, DebugPrecompileHeadersDone(false)
|
||||
, DebugSourcesDone(false)
|
||||
, SourcesAreContextDependent(true)
|
||||
, UtilityItemsDone(false)
|
||||
, SourcesAreContextDependent(Tribool::Indeterminate)
|
||||
{
|
||||
this->Makefile = this->Target->GetMakefile();
|
||||
this->LocalGenerator = lg;
|
||||
@@ -692,7 +692,7 @@ void cmGeneratorTarget::ClearSourcesCache()
|
||||
{
|
||||
this->AllConfigSources.clear();
|
||||
this->KindedSourcesMap.clear();
|
||||
this->SourcesAreContextDependent = true;
|
||||
this->SourcesAreContextDependent = Tribool::Indeterminate;
|
||||
this->Objects.clear();
|
||||
this->VisitedConfigsForObjects.clear();
|
||||
}
|
||||
@@ -1653,10 +1653,13 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
|
||||
uniqueSrcs, debugSources);
|
||||
}
|
||||
|
||||
// Determine if sources are context-dependent or not.
|
||||
if (!contextDependentDirectSources &&
|
||||
!(contextDependentInterfaceSources && numFilesBefore < files.size()) &&
|
||||
!(contextDependentObjects && numFilesBefore2 < files.size())) {
|
||||
this->SourcesAreContextDependent = false;
|
||||
this->SourcesAreContextDependent = Tribool::False;
|
||||
} else {
|
||||
this->SourcesAreContextDependent = Tribool::True;
|
||||
}
|
||||
|
||||
return files;
|
||||
@@ -1731,9 +1734,9 @@ cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries(
|
||||
cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources(
|
||||
std::string const& config) const
|
||||
{
|
||||
// If we already processed one configuration and found no dependenc
|
||||
// If we already processed one configuration and found no dependency
|
||||
// on configuration then always use the one result.
|
||||
if (!this->SourcesAreContextDependent) {
|
||||
if (this->SourcesAreContextDependent == Tribool::False) {
|
||||
return this->KindedSourcesMap.begin()->second;
|
||||
}
|
||||
|
||||
@@ -7518,6 +7521,11 @@ bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& config,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::HasContextDependentSources() const
|
||||
{
|
||||
return this->SourcesAreContextDependent == Tribool::True;
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::IsExecutableWithExports() const
|
||||
{
|
||||
return (this->GetType() == cmStateEnums::EXECUTABLE &&
|
||||
|
||||
@@ -713,6 +713,10 @@ public:
|
||||
bool GetImplibGNUtoMS(std::string const& config, std::string const& gnuName,
|
||||
std::string& out, const char* newExt = nullptr) const;
|
||||
|
||||
/** Can only ever return true if GetSourceFilePaths() was called before.
|
||||
Otherwise, this is indeterminate and false will be assumed/returned! */
|
||||
bool HasContextDependentSources() const;
|
||||
|
||||
bool IsExecutableWithExports() const;
|
||||
|
||||
/** Return whether or not the target has a DLL import library. */
|
||||
@@ -1069,8 +1073,14 @@ private:
|
||||
mutable bool DebugLinkDirectoriesDone;
|
||||
mutable bool DebugPrecompileHeadersDone;
|
||||
mutable bool DebugSourcesDone;
|
||||
mutable bool SourcesAreContextDependent;
|
||||
mutable bool UtilityItemsDone;
|
||||
enum class Tribool
|
||||
{
|
||||
False = 0x0,
|
||||
True = 0x1,
|
||||
Indeterminate = 0x2
|
||||
};
|
||||
mutable Tribool SourcesAreContextDependent;
|
||||
|
||||
bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
|
||||
std::string& out) const;
|
||||
|
||||
@@ -8,7 +8,12 @@ project(ConfigSources CXX)
|
||||
# Source file(s) named with the configuration(s).
|
||||
file(GENERATE
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp"
|
||||
CONTENT "void config_$<CONFIG>() {}\n"
|
||||
CONTENT [[
|
||||
#if defined(_WIN32) && defined(OBJ_SHARED)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void config_$<CONFIG>() {}
|
||||
]]
|
||||
)
|
||||
|
||||
# Per-config sources via INTERFACE_SOURCES.
|
||||
@@ -76,3 +81,13 @@ else()
|
||||
endif()
|
||||
add_library(OneConfigOnly OBJECT "$<$<CONFIG:${one_config}>:${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp>")
|
||||
set_property(TARGET OneConfigOnly PROPERTY LINKER_LANGUAGE CXX)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Makes sure that each configuration uses the correct generated file.
|
||||
add_library(ObjLibFromGeneratedSources OBJECT)
|
||||
set_property(TARGET ObjLibFromGeneratedSources PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
target_compile_definitions(ObjLibFromGeneratedSources PRIVATE OBJ_SHARED)
|
||||
target_sources(ObjLibFromGeneratedSources PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp)
|
||||
add_library(SharedLibFromObjLibFromGeneratedSources SHARED shared.cpp)
|
||||
target_link_libraries(SharedLibFromObjLibFromGeneratedSources PRIVATE ObjLibFromGeneratedSources)
|
||||
|
||||
8
Tests/ConfigSources/shared.cpp
Normal file
8
Tests/ConfigSources/shared.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#if defined(_WIN32)
|
||||
# define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define EXPORT
|
||||
#endif
|
||||
EXPORT void shared()
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user