mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-24 17:18:37 -05:00
Merge topic 'TargetRunTimeDllDirs'
a2c9c4f202Add test for the new TARGET_RUNTIME_DLL_PATHS genexaa68de0a27TARGET_RUNTIME_DLLS: minor refactoring of shared-check.cmake2ce3d62ffbHelp: add documentation for the new TARGET_RUNTIME_DLL_DIRS genexc351dcd967TARGET_RUNTIME_DLL_DIRS: add the new genex to cmGeneratorExpressionNode064c3244daTARGET_RUNTIME_DLLS: fix test for this genex Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Acked-by: Alex <leha-bot@yandex.ru> Merge-request: !8247
This commit is contained in:
@@ -1922,7 +1922,9 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
||||
|
||||
List of DLLs that the target depends on at runtime. This is determined by
|
||||
the locations of all the ``SHARED`` targets in the target's transitive
|
||||
dependencies. Using this generator expression on targets other than
|
||||
dependencies. If only the directories of the DLLs are needed, see the
|
||||
:genex:`TARGET_RUNTIME_DLL_DIRS` generator expression.
|
||||
Using this generator expression on targets other than
|
||||
executables, ``SHARED`` libraries, and ``MODULE`` libraries is an error.
|
||||
**On non-DLL platforms, this expression always evaluates to an empty string**.
|
||||
|
||||
@@ -1954,6 +1956,20 @@ On platforms that support runtime paths (``RPATH``), refer to the
|
||||
:prop_tgt:`INSTALL_RPATH` target property.
|
||||
On Apple platforms, refer to the :prop_tgt:`INSTALL_NAME_DIR` target property.
|
||||
|
||||
.. genex:: $<TARGET_RUNTIME_DLL_DIRS:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
List of the directories which contain the DLLs that the target depends on at
|
||||
runtime (see :genex:`TARGET_RUNTIME_DLLS`). This is determined by
|
||||
the locations of all the ``SHARED`` targets in the target's transitive
|
||||
dependencies. Using this generator expression on targets other than
|
||||
executables, ``SHARED`` libraries, and ``MODULE`` libraries is an error.
|
||||
**On non-DLL platforms, this expression always evaluates to an empty string**.
|
||||
|
||||
This generator expression can e.g. be used to create a batch file using
|
||||
:command:`file(GENERATE)` which sets the PATH environment variable accordingly.
|
||||
|
||||
Export And Install Expressions
|
||||
------------------------------
|
||||
|
||||
|
||||
@@ -2402,15 +2402,12 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
||||
}
|
||||
} targetObjectsNode;
|
||||
|
||||
static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
|
||||
struct TargetRuntimeDllsBaseNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)
|
||||
|
||||
std::string Evaluate(
|
||||
std::vector<std::string> CollectDlls(
|
||||
const std::vector<std::string>& parameters,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content,
|
||||
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
|
||||
const GeneratorExpressionContent* content) const
|
||||
{
|
||||
std::string const& tgtName = parameters.front();
|
||||
cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
|
||||
@@ -2419,7 +2416,7 @@ static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
|
||||
e << "Objects of target \"" << tgtName
|
||||
<< "\" referenced but no such target exists.";
|
||||
reportError(context, content->GetOriginalExpression(), e.str());
|
||||
return std::string();
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
cmStateEnums::TargetType type = gt->GetType();
|
||||
if (type != cmStateEnums::EXECUTABLE &&
|
||||
@@ -2430,7 +2427,7 @@ static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
|
||||
<< "\" referenced but is not one of the allowed target types "
|
||||
<< "(EXECUTABLE, SHARED, MODULE).";
|
||||
reportError(context, content->GetOriginalExpression(), e.str());
|
||||
return std::string();
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
if (auto* cli = gt->GetLinkInformation(context->Config)) {
|
||||
@@ -2443,13 +2440,51 @@ static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
|
||||
}
|
||||
}
|
||||
|
||||
return cmJoin(dllPaths, ";");
|
||||
return dllPaths;
|
||||
}
|
||||
|
||||
return "";
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
};
|
||||
|
||||
static const struct TargetRuntimeDllsNode : public TargetRuntimeDllsBaseNode
|
||||
{
|
||||
TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)
|
||||
|
||||
std::string Evaluate(
|
||||
const std::vector<std::string>& parameters,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content,
|
||||
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
|
||||
{
|
||||
std::vector<std::string> dlls = CollectDlls(parameters, context, content);
|
||||
return cmJoin(dlls, ";");
|
||||
}
|
||||
} targetRuntimeDllsNode;
|
||||
|
||||
static const struct TargetRuntimeDllDirsNode : public TargetRuntimeDllsBaseNode
|
||||
{
|
||||
TargetRuntimeDllDirsNode() {} // NOLINT(modernize-use-equals-default)
|
||||
|
||||
std::string Evaluate(
|
||||
const std::vector<std::string>& parameters,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content,
|
||||
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
|
||||
{
|
||||
std::vector<std::string> dlls = CollectDlls(parameters, context, content);
|
||||
std::vector<std::string> dllDirs;
|
||||
for (const std::string& dll : dlls) {
|
||||
std::string directory = cmSystemTools::GetFilenamePath(dll);
|
||||
if (std::find(dllDirs.begin(), dllDirs.end(), directory) ==
|
||||
dllDirs.end()) {
|
||||
dllDirs.push_back(directory);
|
||||
}
|
||||
}
|
||||
return cmJoin(dllDirs, ";");
|
||||
}
|
||||
} targetRuntimeDllDirsNode;
|
||||
|
||||
static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default)
|
||||
@@ -3774,6 +3809,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
|
||||
{ "TARGET_NAME_IF_EXISTS", &targetNameIfExistsNode },
|
||||
{ "TARGET_GENEX_EVAL", &targetGenexEvalNode },
|
||||
{ "TARGET_RUNTIME_DLLS", &targetRuntimeDllsNode },
|
||||
{ "TARGET_RUNTIME_DLL_DIRS", &targetRuntimeDllDirsNode },
|
||||
{ "GENEX_EVAL", &genexEvalNode },
|
||||
{ "BUILD_INTERFACE", &buildInterfaceNode },
|
||||
{ "INSTALL_INTERFACE", &installInterfaceNode },
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
function(check_genex expected actual)
|
||||
if(NOT expected STREQUAL actual)
|
||||
string(APPEND RunCMake_TEST_FAILED "Expected DLLs:\n")
|
||||
foreach(dll IN LISTS expected)
|
||||
string(APPEND RunCMake_TEST_FAILED " ${dll}\n")
|
||||
endforeach()
|
||||
string(APPEND RunCMake_TEST_FAILED "Actual DLLs:\n")
|
||||
foreach(dll IN LISTS actual)
|
||||
string(APPEND RunCMake_TEST_FAILED " ${dll}\n")
|
||||
endforeach()
|
||||
endif()
|
||||
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
include("${RunCMake_TEST_BINARY_DIR}/dlls.cmake")
|
||||
@@ -0,0 +1,15 @@
|
||||
function(check_genex expected actual)
|
||||
if(NOT expected STREQUAL actual)
|
||||
string(APPEND RunCMake_TEST_FAILED "Expected items:\n")
|
||||
foreach(item IN LISTS expected)
|
||||
string(APPEND RunCMake_TEST_FAILED " ${item}\n")
|
||||
endforeach()
|
||||
string(APPEND RunCMake_TEST_FAILED "Actual items:\n")
|
||||
foreach(item IN LISTS actual)
|
||||
string(APPEND RunCMake_TEST_FAILED " ${item}\n")
|
||||
endforeach()
|
||||
endif()
|
||||
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
include("${RunCMake_TEST_BINARY_DIR}/dlls.cmake")
|
||||
@@ -4,6 +4,10 @@ add_executable(exe main.c)
|
||||
add_library(lib1 SHARED lib1.c)
|
||||
add_library(lib2 SHARED lib2.c)
|
||||
add_library(lib3 SHARED lib3.c)
|
||||
if(WIN32 OR CYGWIN)
|
||||
set_property(TARGET lib3 PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/SomeSubDir/")
|
||||
endif()
|
||||
|
||||
add_library(static STATIC static.c)
|
||||
add_library(imported SHARED IMPORTED)
|
||||
set_property(TARGET imported PROPERTY IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/imported.dll")
|
||||
@@ -26,9 +30,16 @@ if(WIN32 OR CYGWIN)
|
||||
"$<TARGET_FILE:lib3>"
|
||||
"$<TARGET_FILE:lib2>"
|
||||
)
|
||||
set(expected_dll_dirs
|
||||
"$<PATH:GET_PARENT_PATH,$<TARGET_FILE:lib2>>"
|
||||
"$<PATH:GET_PARENT_PATH,$<TARGET_FILE:imported>>"
|
||||
"$<PATH:GET_PARENT_PATH,$<TARGET_FILE:lib3>>"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(content "check_genex(\"${expected_dlls}\" \"$<TARGET_RUNTIME_DLLS:exe>\")\n")
|
||||
set(content "check_genex(\"${expected_dlls}\" \"$<TARGET_RUNTIME_DLLS:exe>\")
|
||||
check_genex(\"${expected_dll_dirs}\" \"$<TARGET_RUNTIME_DLL_DIRS:exe>\")\n")
|
||||
|
||||
set(condition)
|
||||
get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(multi_config)
|
||||
|
||||
Reference in New Issue
Block a user