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:
commit
e25f95c4cc
@ -654,6 +654,7 @@ Variables for Languages
|
|||||||
/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES
|
/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES
|
||||||
/variable/CMAKE_LANG_STANDARD_LATEST
|
/variable/CMAKE_LANG_STANDARD_LATEST
|
||||||
/variable/CMAKE_LANG_STANDARD_LIBRARIES
|
/variable/CMAKE_LANG_STANDARD_LIBRARIES
|
||||||
|
/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES
|
||||||
/variable/CMAKE_LANG_STANDARD_REQUIRED
|
/variable/CMAKE_LANG_STANDARD_REQUIRED
|
||||||
/variable/CMAKE_OBJC_EXTENSIONS
|
/variable/CMAKE_OBJC_EXTENSIONS
|
||||||
/variable/CMAKE_OBJC_STANDARD
|
/variable/CMAKE_OBJC_STANDARD
|
||||||
|
6
Help/release/dev/standard-link-directories.rst
Normal file
6
Help/release/dev/standard-link-directories.rst
Normal 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.
|
14
Help/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES.rst
Normal file
14
Help/variable/CMAKE_LANG_STANDARD_LINK_DIRECTORIES.rst
Normal 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`.
|
@ -3994,7 +3994,6 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
|||||||
{
|
{
|
||||||
BuildObjectListOrString libSearchPaths(this, true);
|
BuildObjectListOrString libSearchPaths(this, true);
|
||||||
|
|
||||||
std::string linkDirs;
|
|
||||||
for (auto const& libDir : cli->GetDirectories()) {
|
for (auto const& libDir : cli->GetDirectories()) {
|
||||||
if (!libDir.empty() && libDir != "/usr/lib"_s) {
|
if (!libDir.empty() && libDir != "/usr/lib"_s) {
|
||||||
cmPolicies::PolicyStatus cmp0142 =
|
cmPolicies::PolicyStatus cmp0142 =
|
||||||
@ -4012,6 +4011,16 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
|||||||
for (auto& libDir : linkSearchPaths) {
|
for (auto& libDir : linkSearchPaths) {
|
||||||
libSearchPaths.Add(this->XCodeEscapePath(libDir));
|
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()) {
|
if (!libSearchPaths.IsEmpty()) {
|
||||||
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
|
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
|
||||||
libSearchPaths.CreateList(),
|
libSearchPaths.CreateList(),
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
#include "cmGeneratorTarget.h"
|
#include "cmGeneratorTarget.h"
|
||||||
|
#include "cmList.h"
|
||||||
#include "cmListFileCache.h"
|
#include "cmListFileCache.h"
|
||||||
#include "cmOutputConverter.h"
|
#include "cmOutputConverter.h"
|
||||||
#include "cmStateTypes.h"
|
#include "cmStateTypes.h"
|
||||||
@ -112,18 +113,20 @@ std::string cmLinkLineComputer::ConvertToOutputForExisting(
|
|||||||
|
|
||||||
std::string cmLinkLineComputer::ComputeLinkPath(
|
std::string cmLinkLineComputer::ComputeLinkPath(
|
||||||
cmComputeLinkInformation& cli, std::string const& libPathFlag,
|
cmComputeLinkInformation& cli, std::string const& libPathFlag,
|
||||||
std::string const& libPathTerminator)
|
std::string const& libPathTerminator, std::string const& stdLinkDirString)
|
||||||
{
|
{
|
||||||
std::string linkPath;
|
std::string linkPath;
|
||||||
std::vector<BT<std::string>> linkPathList;
|
std::vector<BT<std::string>> linkPathList;
|
||||||
this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPathList);
|
this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, stdLinkDirString,
|
||||||
|
linkPathList);
|
||||||
cli.AppendValues(linkPath, linkPathList);
|
cli.AppendValues(linkPath, linkPathList);
|
||||||
return linkPath;
|
return linkPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmLinkLineComputer::ComputeLinkPath(
|
void cmLinkLineComputer::ComputeLinkPath(
|
||||||
cmComputeLinkInformation& cli, std::string const& libPathFlag,
|
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") {
|
if (cli.GetLinkLanguage() == "Swift") {
|
||||||
std::string linkPathNoBT;
|
std::string linkPathNoBT;
|
||||||
@ -160,6 +163,12 @@ void cmLinkLineComputer::ComputeLinkPath(
|
|||||||
libPathTerminator, " ");
|
libPathTerminator, " ");
|
||||||
linkPath.emplace_back(libDir);
|
linkPath.emplace_back(libDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& linkDir : cmList(stdLinkDirString)) {
|
||||||
|
linkPath.emplace_back(cmStrCat(' ', libPathFlag,
|
||||||
|
this->ConvertToOutputForExisting(linkDir),
|
||||||
|
libPathTerminator, ' '));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli)
|
std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli)
|
||||||
|
@ -36,11 +36,13 @@ public:
|
|||||||
|
|
||||||
std::string ComputeLinkPath(cmComputeLinkInformation& cli,
|
std::string ComputeLinkPath(cmComputeLinkInformation& cli,
|
||||||
std::string const& libPathFlag,
|
std::string const& libPathFlag,
|
||||||
std::string const& libPathTerminator);
|
std::string const& libPathTerminator,
|
||||||
|
std::string const& stdLinkDirString);
|
||||||
|
|
||||||
void ComputeLinkPath(cmComputeLinkInformation& cli,
|
void ComputeLinkPath(cmComputeLinkInformation& cli,
|
||||||
std::string const& libPathFlag,
|
std::string const& libPathFlag,
|
||||||
std::string const& libPathTerminator,
|
std::string const& libPathTerminator,
|
||||||
|
std::string const& stdLinkDirString,
|
||||||
std::vector<BT<std::string>>& linkPath);
|
std::vector<BT<std::string>>& linkPath);
|
||||||
|
|
||||||
std::string ComputeFrameworkPath(cmComputeLinkInformation& cli,
|
std::string ComputeFrameworkPath(cmComputeLinkInformation& cli,
|
||||||
|
@ -1897,6 +1897,10 @@ void cmLocalGenerator::OutputLinkLibraries(
|
|||||||
this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
|
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.
|
// Add standard libraries for this language.
|
||||||
std::string stdLibString = this->Makefile->GetSafeDefinition(
|
std::string stdLibString = this->Makefile->GetSafeDefinition(
|
||||||
cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES"));
|
cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES"));
|
||||||
@ -1907,7 +1911,7 @@ void cmLocalGenerator::OutputLinkLibraries(
|
|||||||
|
|
||||||
frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
|
frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
|
||||||
linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator,
|
linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator,
|
||||||
linkPath);
|
stdLinkDirString, linkPath);
|
||||||
linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries);
|
linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,7 +1123,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
|
|||||||
this->WriteTargetVersionAttribute(fout, target);
|
this->WriteTargetVersionAttribute(fout, target);
|
||||||
linkOptions.OutputFlagMap(fout, 4);
|
linkOptions.OutputFlagMap(fout, 4);
|
||||||
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
|
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";
|
fout << "\"\n";
|
||||||
temp =
|
temp =
|
||||||
cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
|
cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
|
||||||
@ -1206,7 +1209,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
|
|||||||
this->WriteTargetVersionAttribute(fout, target);
|
this->WriteTargetVersionAttribute(fout, target);
|
||||||
linkOptions.OutputFlagMap(fout, 4);
|
linkOptions.OutputFlagMap(fout, 4);
|
||||||
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
|
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";
|
fout << "\"\n";
|
||||||
std::string path = this->ConvertToXMLOutputPathSingle(
|
std::string path = this->ConvertToXMLOutputPathSingle(
|
||||||
target->GetPDBDirectory(configName));
|
target->GetPDBDirectory(configName));
|
||||||
@ -1356,9 +1362,11 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
|
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 = "";
|
const char* comma = "";
|
||||||
|
|
||||||
for (std::string dir : dirs) {
|
for (std::string dir : dirs) {
|
||||||
// Remove any trailing slash and skip empty paths.
|
// Remove any trailing slash and skip empty paths.
|
||||||
if (dir.back() == '/') {
|
if (dir.back() == '/') {
|
||||||
@ -1384,6 +1392,12 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
|
|||||||
<< ',' << this->ConvertToXMLOutputPath(dir);
|
<< ',' << this->ConvertToXMLOutputPath(dir);
|
||||||
comma = ",";
|
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,
|
void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
|
@ -125,6 +125,7 @@ private:
|
|||||||
std::string const& config,
|
std::string const& config,
|
||||||
cmGeneratorTarget* target);
|
cmGeneratorTarget* target);
|
||||||
void OutputLibraryDirectories(std::ostream& fout,
|
void OutputLibraryDirectories(std::ostream& fout,
|
||||||
|
std::vector<std::string> const& stdlink,
|
||||||
std::vector<std::string> const& dirs);
|
std::vector<std::string> const& dirs);
|
||||||
void WriteProjectSCC(std::ostream& fout, cmGeneratorTarget* target);
|
void WriteProjectSCC(std::ostream& fout, cmGeneratorTarget* target);
|
||||||
void WriteProjectStart(std::ostream& fout, const std::string& libName,
|
void WriteProjectStart(std::ostream& fout, const std::string& libName,
|
||||||
|
@ -4457,14 +4457,21 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
|
|||||||
this->AddTargetsFileAndConfigPair(ti, config);
|
this->AddTargetsFileAndConfigPair(ti, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> const& ldirs = cli.GetDirectories();
|
|
||||||
std::vector<std::string> linkDirs;
|
std::vector<std::string> linkDirs;
|
||||||
|
std::vector<std::string> const& ldirs = cli.GetDirectories();
|
||||||
for (std::string const& d : ldirs) {
|
for (std::string const& d : ldirs) {
|
||||||
// first just full path
|
// first just full path
|
||||||
linkDirs.push_back(d);
|
linkDirs.push_back(d);
|
||||||
// next path with configuration type Debug, Release, etc
|
// next path with configuration type Debug, Release, etc
|
||||||
linkDirs.emplace_back(cmStrCat(d, "/$(Configuration)"));
|
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)");
|
linkDirs.push_back("%(AdditionalLibraryDirectories)");
|
||||||
linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs);
|
linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs);
|
||||||
|
|
||||||
|
@ -492,6 +492,7 @@ if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
add_RunCMake_test(ScriptMode)
|
add_RunCMake_test(ScriptMode)
|
||||||
|
add_RunCMake_test(StandardLinkDirectories)
|
||||||
add_RunCMake_test(Swift -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
|
add_RunCMake_test(Swift -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
|
||||||
-DCMake_TEST_Swift=${CMake_TEST_Swift}
|
-DCMake_TEST_Swift=${CMake_TEST_Swift}
|
||||||
-DXCODE_VERSION=${XCODE_VERSION})
|
-DXCODE_VERSION=${XCODE_VERSION})
|
||||||
|
3
Tests/RunCMake/StandardLinkDirectories/CMakeLists.txt
Normal file
3
Tests/RunCMake/StandardLinkDirectories/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.30)
|
||||||
|
project(${RunCMake_TEST} LANGUAGES C)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
22
Tests/RunCMake/StandardLinkDirectories/RunCMakeTest.cmake
Normal file
22
Tests/RunCMake/StandardLinkDirectories/RunCMakeTest.cmake
Normal 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()
|
1
Tests/RunCMake/StandardLinkDirectories/TestApp.cmake
Normal file
1
Tests/RunCMake/StandardLinkDirectories/TestApp.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(TestApp)
|
@ -0,0 +1,2 @@
|
|||||||
|
add_executable(TestApp TestApp.c)
|
||||||
|
target_link_libraries(TestApp PRIVATE SLD)
|
6
Tests/RunCMake/StandardLinkDirectories/TestApp/TestApp.c
Normal file
6
Tests/RunCMake/StandardLinkDirectories/TestApp/TestApp.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
int TestSymbol(void);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return TestSymbol();
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
[^0]
|
1
Tests/RunCMake/StandardLinkDirectories/TestLib.cmake
Normal file
1
Tests/RunCMake/StandardLinkDirectories/TestLib.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(TestLib)
|
@ -0,0 +1,2 @@
|
|||||||
|
add_library(SLD TestLib.c)
|
||||||
|
set_target_properties(SLD PROPERTIES ARCHIVE_OUTPUT_DIRECTORY $<1:lib>)
|
4
Tests/RunCMake/StandardLinkDirectories/TestLib/TestLib.c
Normal file
4
Tests/RunCMake/StandardLinkDirectories/TestLib/TestLib.c
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
int TestSymbol(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user