summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVito Gamberini <vito.gamberini@kitware.com>2024-08-07 18:17:18 (GMT)
committerVito Gamberini <vito.gamberini@kitware.com>2024-08-28 19:54:43 (GMT)
commit20e9b59d5e215768956ec131e80e540ed60d2487 (patch)
treea2fd3c4d6adedfe1309526701b240f91955e4cc7
parent041a482079baf690f1bf8e9cdc8a7a1922016267 (diff)
downloadCMake-20e9b59d5e215768956ec131e80e540ed60d2487.zip
CMake-20e9b59d5e215768956ec131e80e540ed60d2487.tar.gz
CMake-20e9b59d5e215768956ec131e80e540ed60d2487.tar.bz2
Linking: Add CMAKE_LANG_STANDARD_LINK_DIRECTORIES
Closes: #18222
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/release/dev/standard-link-directories.rst6
-rw-r--r--Help/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES.rst14
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx11
-rw-r--r--Source/cmLinkLineComputer.cxx15
-rw-r--r--Source/cmLinkLineComputer.h4
-rw-r--r--Source/cmLocalGenerator.cxx6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx20
-rw-r--r--Source/cmLocalVisualStudio7Generator.h1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx9
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestApp.cmake1
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestApp/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestApp/TestApp.c6
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestAppBad-result.txt1
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestLib.cmake1
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestLib/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/StandardLinkDirectories/TestLib/TestLib.c4
20 files changed, 120 insertions, 10 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 1d6331e..48d4a5c 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -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
diff --git a/Help/release/dev/standard-link-directories.rst b/Help/release/dev/standard-link-directories.rst
new file mode 100644
index 0000000..5c4f287
--- /dev/null
+++ b/Help/release/dev/standard-link-directories.rst
@@ -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.
diff --git a/Help/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES.rst
new file mode 100644
index 0000000..15aec23
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES.rst
@@ -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`.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index aa948a5..7fa21d0 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -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(),
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index a29e33f..e823337 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -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)
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
index afd3944..63cbeb2 100644
--- a/Source/cmLinkLineComputer.h
+++ b/Source/cmLinkLineComputer.h
@@ -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,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 601f4b3..2dc8351 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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);
}
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 8577cc4..bf32ce5 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -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,
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index bb05226..7c395d6 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -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,
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 54bab9f..0a40645 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -4465,14 +4465,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);
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 112e530..383c80f 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -491,6 +491,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})
diff --git a/Tests/RunCMake/StandardLinkDirectories/CMakeLists.txt b/Tests/RunCMake/StandardLinkDirectories/CMakeLists.txt
new file mode 100644
index 0000000..ccf88ee
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.30)
+project(${RunCMake_TEST} LANGUAGES C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/StandardLinkDirectories/RunCMakeTest.cmake b/Tests/RunCMake/StandardLinkDirectories/RunCMakeTest.cmake
new file mode 100644
index 0000000..6760ffc
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/RunCMakeTest.cmake
@@ -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()
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestApp.cmake b/Tests/RunCMake/StandardLinkDirectories/TestApp.cmake
new file mode 100644
index 0000000..53a9c9a
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestApp.cmake
@@ -0,0 +1 @@
+add_subdirectory(TestApp)
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestApp/CMakeLists.txt b/Tests/RunCMake/StandardLinkDirectories/TestApp/CMakeLists.txt
new file mode 100644
index 0000000..92dd52f
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestApp/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_executable(TestApp TestApp.c)
+target_link_libraries(TestApp PRIVATE SLD)
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestApp/TestApp.c b/Tests/RunCMake/StandardLinkDirectories/TestApp/TestApp.c
new file mode 100644
index 0000000..66630d8
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestApp/TestApp.c
@@ -0,0 +1,6 @@
+int TestSymbol(void);
+
+int main(void)
+{
+ return TestSymbol();
+}
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestAppBad-result.txt b/Tests/RunCMake/StandardLinkDirectories/TestAppBad-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestAppBad-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestLib.cmake b/Tests/RunCMake/StandardLinkDirectories/TestLib.cmake
new file mode 100644
index 0000000..aa8a6c3
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestLib.cmake
@@ -0,0 +1 @@
+add_subdirectory(TestLib)
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestLib/CMakeLists.txt b/Tests/RunCMake/StandardLinkDirectories/TestLib/CMakeLists.txt
new file mode 100644
index 0000000..bf41631
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestLib/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(SLD TestLib.c)
+set_target_properties(SLD PROPERTIES ARCHIVE_OUTPUT_DIRECTORY $<1:lib>)
diff --git a/Tests/RunCMake/StandardLinkDirectories/TestLib/TestLib.c b/Tests/RunCMake/StandardLinkDirectories/TestLib/TestLib.c
new file mode 100644
index 0000000..e5d2b1c
--- /dev/null
+++ b/Tests/RunCMake/StandardLinkDirectories/TestLib/TestLib.c
@@ -0,0 +1,4 @@
+int TestSymbol(void)
+{
+ return 0;
+}