Merge topic 'standard-link-directories'

20e9b59d5e Linking: Add CMAKE_LANG_STANDARD_LINK_DIRECTORIES

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !9707
This commit is contained in:
Brad King 2024-08-29 12:31:01 +00:00 committed by Kitware Robot
commit e25f95c4cc
20 changed files with 120 additions and 10 deletions

View File

@ -654,6 +654,7 @@ Variables for Languages
/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES
/variable/CMAKE_LANG_STANDARD_LATEST
/variable/CMAKE_LANG_STANDARD_LIBRARIES
/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES
/variable/CMAKE_LANG_STANDARD_REQUIRED
/variable/CMAKE_OBJC_EXTENSIONS
/variable/CMAKE_OBJC_STANDARD

View File

@ -0,0 +1,6 @@
standard-link-directories
-------------------------
* The :variable:`CMAKE_<LANG>_STANDARD_LINK_DIRECTORIES` variable was added.
Toolchain files can set this variable to control which link library directory
paths are always passed to the compiler for the specified language.

View File

@ -0,0 +1,14 @@
CMAKE_<LANG>_STANDARD_LINK_DIRECTORIES
--------------------------------------
.. versionadded:: 3.31
Link directories specified for every executable and library linked
for language ``<LANG>``. This is meant for specification of system
link directories needed by the language for the current platform.
This variable should not be set by project code. It is meant to be set by
CMake's platform information modules for the current toolchain, or by a
toolchain file when used with :variable:`CMAKE_TOOLCHAIN_FILE`.
See also :variable:`CMAKE_<LANG>_STANDARD_LIBRARIES`.

View File

@ -3994,7 +3994,6 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
{
BuildObjectListOrString libSearchPaths(this, true);
std::string linkDirs;
for (auto const& libDir : cli->GetDirectories()) {
if (!libDir.empty() && libDir != "/usr/lib"_s) {
cmPolicies::PolicyStatus cmp0142 =
@ -4012,6 +4011,16 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
for (auto& libDir : linkSearchPaths) {
libSearchPaths.Add(this->XCodeEscapePath(libDir));
}
// Add toolchain specified language link directories
std::string const& linkDirsString =
this->Makefiles.front()->GetSafeDefinition(cmStrCat(
"CMAKE_", cli->GetLinkLanguage(), "_STANDARD_LINK_DIRECTORIES"));
for (const auto& libDir : cmList(linkDirsString)) {
libSearchPaths.Add(this->XCodeEscapePath(libDir));
}
if (!libSearchPaths.IsEmpty()) {
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
libSearchPaths.CreateList(),

View File

@ -9,6 +9,7 @@
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmOutputConverter.h"
#include "cmStateTypes.h"
@ -112,18 +113,20 @@ std::string cmLinkLineComputer::ConvertToOutputForExisting(
std::string cmLinkLineComputer::ComputeLinkPath(
cmComputeLinkInformation& cli, std::string const& libPathFlag,
std::string const& libPathTerminator)
std::string const& libPathTerminator, std::string const& stdLinkDirString)
{
std::string linkPath;
std::vector<BT<std::string>> linkPathList;
this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPathList);
this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, stdLinkDirString,
linkPathList);
cli.AppendValues(linkPath, linkPathList);
return linkPath;
}
void cmLinkLineComputer::ComputeLinkPath(
cmComputeLinkInformation& cli, std::string const& libPathFlag,
std::string const& libPathTerminator, std::vector<BT<std::string>>& linkPath)
std::string const& libPathTerminator, std::string const& stdLinkDirString,
std::vector<BT<std::string>>& linkPath)
{
if (cli.GetLinkLanguage() == "Swift") {
std::string linkPathNoBT;
@ -160,6 +163,12 @@ void cmLinkLineComputer::ComputeLinkPath(
libPathTerminator, " ");
linkPath.emplace_back(libDir);
}
for (auto& linkDir : cmList(stdLinkDirString)) {
linkPath.emplace_back(cmStrCat(' ', libPathFlag,
this->ConvertToOutputForExisting(linkDir),
libPathTerminator, ' '));
}
}
std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli)

View File

@ -36,11 +36,13 @@ public:
std::string ComputeLinkPath(cmComputeLinkInformation& cli,
std::string const& libPathFlag,
std::string const& libPathTerminator);
std::string const& libPathTerminator,
std::string const& stdLinkDirString);
void ComputeLinkPath(cmComputeLinkInformation& cli,
std::string const& libPathFlag,
std::string const& libPathTerminator,
std::string const& stdLinkDirString,
std::vector<BT<std::string>>& linkPath);
std::string ComputeFrameworkPath(cmComputeLinkInformation& cli,

View File

@ -1897,6 +1897,10 @@ void cmLocalGenerator::OutputLinkLibraries(
this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
}
// Add standard link directories for this language
std::string stdLinkDirString = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LINK_DIRECTORIES"));
// Add standard libraries for this language.
std::string stdLibString = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES"));
@ -1907,7 +1911,7 @@ void cmLocalGenerator::OutputLinkLibraries(
frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator,
linkPath);
stdLinkDirString, linkPath);
linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries);
}

View File

@ -1123,7 +1123,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
this->WriteTargetVersionAttribute(fout, target);
linkOptions.OutputFlagMap(fout, 4);
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories());
std::string const& linkDirsString = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LINK_DIRECTORIES"));
this->OutputLibraryDirectories(fout, cmList(linkDirsString),
cli.GetDirectories());
fout << "\"\n";
temp =
cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
@ -1206,7 +1209,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
this->WriteTargetVersionAttribute(fout, target);
linkOptions.OutputFlagMap(fout, 4);
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories());
std::string const& linkDirsString = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LINK_DIRECTORIES"));
this->OutputLibraryDirectories(fout, cmList(linkDirsString),
cli.GetDirectories());
fout << "\"\n";
std::string path = this->ConvertToXMLOutputPathSingle(
target->GetPDBDirectory(configName));
@ -1356,9 +1362,11 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
}
void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
std::ostream& fout, std::vector<std::string> const& dirs)
std::ostream& fout, std::vector<std::string> const& stdlink,
std::vector<std::string> const& dirs)
{
const char* comma = "";
for (std::string dir : dirs) {
// Remove any trailing slash and skip empty paths.
if (dir.back() == '/') {
@ -1384,6 +1392,12 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
<< ',' << this->ConvertToXMLOutputPath(dir);
comma = ",";
}
// No special processing on toolchain-defined standard link directory paths
for (const auto& dir : stdlink) {
fout << comma << this->ConvertToXMLOutputPath(dir);
comma = ",";
}
}
void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,

View File

@ -125,6 +125,7 @@ private:
std::string const& config,
cmGeneratorTarget* target);
void OutputLibraryDirectories(std::ostream& fout,
std::vector<std::string> const& stdlink,
std::vector<std::string> const& dirs);
void WriteProjectSCC(std::ostream& fout, cmGeneratorTarget* target);
void WriteProjectStart(std::ostream& fout, const std::string& libName,

View File

@ -4457,14 +4457,21 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
this->AddTargetsFileAndConfigPair(ti, config);
}
std::vector<std::string> const& ldirs = cli.GetDirectories();
std::vector<std::string> linkDirs;
std::vector<std::string> const& ldirs = cli.GetDirectories();
for (std::string const& d : ldirs) {
// first just full path
linkDirs.push_back(d);
// next path with configuration type Debug, Release, etc
linkDirs.emplace_back(cmStrCat(d, "/$(Configuration)"));
}
std::string const& linkDirsString = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LINK_DIRECTORIES"));
for (const std::string& d : cmList(linkDirsString)) {
linkDirs.push_back(d);
}
linkDirs.push_back("%(AdditionalLibraryDirectories)");
linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs);

View File

@ -492,6 +492,7 @@ if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
)
endif()
add_RunCMake_test(ScriptMode)
add_RunCMake_test(StandardLinkDirectories)
add_RunCMake_test(Swift -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DCMake_TEST_Swift=${CMake_TEST_Swift}
-DXCODE_VERSION=${XCODE_VERSION})

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.30)
project(${RunCMake_TEST} LANGUAGES C)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,22 @@
include(RunCMake)
# Link should succeed
block()
set(libdir ${RunCMake_BINARY_DIR}/TestLib-build/TestLib/lib)
run_cmake(TestLib)
run_cmake_with_options(TestApp "-DCMAKE_C_STANDARD_LINK_DIRECTORIES=${libdir}")
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_OUTPUT_MERGE 1)
run_cmake_command(TestLib ${CMAKE_COMMAND} --build .)
run_cmake_command(TestAppGood ${CMAKE_COMMAND} --build ../TestApp-build)
endblock()
# Link should fail
block()
run_cmake(TestLib)
run_cmake(TestApp)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_OUTPUT_MERGE 1)
run_cmake_command(TestLib ${CMAKE_COMMAND} --build .)
run_cmake_command(TestAppBad ${CMAKE_COMMAND} --build ../TestApp-build)
endblock()

View File

@ -0,0 +1 @@
add_subdirectory(TestApp)

View File

@ -0,0 +1,2 @@
add_executable(TestApp TestApp.c)
target_link_libraries(TestApp PRIVATE SLD)

View File

@ -0,0 +1,6 @@
int TestSymbol(void);
int main(void)
{
return TestSymbol();
}

View File

@ -0,0 +1 @@
[^0]

View File

@ -0,0 +1 @@
add_subdirectory(TestLib)

View File

@ -0,0 +1,2 @@
add_library(SLD TestLib.c)
set_target_properties(SLD PROPERTIES ARCHIVE_OUTPUT_DIRECTORY $<1:lib>)

View File

@ -0,0 +1,4 @@
int TestSymbol(void)
{
return 0;
}