diff options
-rw-r--r-- | Help/command/link_directories.rst | 8 | ||||
-rw-r--r-- | Help/manual/cmake-variables.7.rst | 1 | ||||
-rw-r--r-- | Help/release/dev/link_directories-enhancements.rst | 5 | ||||
-rw-r--r-- | Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst | 9 | ||||
-rw-r--r-- | Source/cmLinkDirectoriesCommand.cxx | 25 | ||||
-rw-r--r-- | Source/cmLinkDirectoriesCommand.h | 3 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 11 | ||||
-rw-r--r-- | Source/cmMakefile.h | 2 | ||||
-rw-r--r-- | Source/cmStateDirectory.cxx | 27 | ||||
-rw-r--r-- | Source/cmStateDirectory.h | 2 | ||||
-rw-r--r-- | Tests/CMakeCommands/link_directories/CMakeLists.txt | 30 | ||||
-rw-r--r-- | Tests/CMakeCommands/link_directories/LinkDirectoriesExe.c | 4 | ||||
-rw-r--r-- | Tests/CMakeLists.txt | 3 |
13 files changed, 120 insertions, 10 deletions
diff --git a/Help/command/link_directories.rst b/Help/command/link_directories.rst index 3efa8e5..1dce9a0 100644 --- a/Help/command/link_directories.rst +++ b/Help/command/link_directories.rst @@ -5,7 +5,7 @@ Add directories in which the linker will look for libraries. :: - link_directories(directory1 [directory2 ...]) + link_directories([AFTER|BEFORE] directory1 [directory2 ...]) Add the paths in which the linker should search for libraries. Relative paths given to this command are interpreted as relative to @@ -16,6 +16,12 @@ property for the current ``CMakeLists.txt`` file, converting relative paths to absolute as needed. The command will apply only to targets created after it is called. +By default the directories specified are appended onto the current list of +directories. This default behavior can be changed by setting +:variable:`CMAKE_LINK_DIRECTORIES_BEFORE` to ``ON``. By using +``AFTER`` or ``BEFORE`` explicitly, you can select between appending and +prepending, independent of the default. + Arguments to ``link_directories`` may use "generator expressions" with the syntax "$<...>". See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 6071999..78353fb 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -179,6 +179,7 @@ Variables that Change Behavior /variable/CMAKE_INSTALL_PREFIX /variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT /variable/CMAKE_LIBRARY_PATH + /variable/CMAKE_LINK_DIRECTORIES_BEFORE /variable/CMAKE_MFC_FLAG /variable/CMAKE_MODULE_PATH /variable/CMAKE_NOT_USING_CONFIG_FLAGS diff --git a/Help/release/dev/link_directories-enhancements.rst b/Help/release/dev/link_directories-enhancements.rst new file mode 100644 index 0000000..2521fa1 --- /dev/null +++ b/Help/release/dev/link_directories-enhancements.rst @@ -0,0 +1,5 @@ +link_directories-enhancements +----------------------------- + +* :command:`link_directories` command gains capability to control directories + insertion position. diff --git a/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst b/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst new file mode 100644 index 0000000..026ca35 --- /dev/null +++ b/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst @@ -0,0 +1,9 @@ +CMAKE_LINK_DIRECTORIES_BEFORE +----------------------------- + +Whether to append or prepend directories by default in +:command:`link_directories`. + +This variable affects the default behavior of the :command:`link_directories` +command. Setting this variable to ``ON`` is equivalent to using the ``BEFORE`` +option in all uses of that command. diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index 5c52c76..10425fd 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmPolicies.h" @@ -20,13 +21,29 @@ bool cmLinkDirectoriesCommand::InitialPass( return true; } - for (std::string const& i : args) { - this->AddLinkDir(i); + bool before = this->Makefile->IsOn("CMAKE_LINK_DIRECTORIES_BEFORE"); + + auto i = args.cbegin(); + if ((*i) == "BEFORE") { + before = true; + ++i; + } else if ((*i) == "AFTER") { + before = false; + ++i; + } + + std::vector<std::string> directories; + for (; i != args.cend(); ++i) { + this->AddLinkDir(*i, directories); } + + this->Makefile->AddLinkDirectory(cmJoin(directories, ";"), before); + return true; } -void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir) +void cmLinkDirectoriesCommand::AddLinkDir( + std::string const& dir, std::vector<std::string>& directories) { std::string unixPath = dir; cmSystemTools::ConvertToUnixSlashes(unixPath); @@ -64,5 +81,5 @@ void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir) unixPath = tmp; } } - this->Makefile->AddLinkDirectory(unixPath); + directories.push_back(unixPath); } diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h index 3fd4e50..ae4fb7f 100644 --- a/Source/cmLinkDirectoriesCommand.h +++ b/Source/cmLinkDirectoriesCommand.h @@ -36,7 +36,8 @@ public: cmExecutionStatus& status) override; private: - void AddLinkDir(std::string const& dir); + void AddLinkDir(std::string const& dir, + std::vector<std::string>& directories); }; #endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 963bb44..8d163b7 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1248,9 +1248,16 @@ void cmMakefile::AddLinkOption(std::string const& option) this->AppendProperty("LINK_OPTIONS", option.c_str()); } -void cmMakefile::AddLinkDirectory(std::string const& directory) +void cmMakefile::AddLinkDirectory(std::string const& directory, bool before) { - this->AppendProperty("LINK_DIRECTORIES", directory.c_str()); + cmListFileBacktrace lfbt = this->GetBacktrace(); + if (before) { + this->StateSnapshot.GetDirectory().PrependLinkDirectoriesEntry(directory, + lfbt); + } else { + this->StateSnapshot.GetDirectory().AppendLinkDirectoriesEntry(directory, + lfbt); + } } bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index cde661b..b30f281 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -182,7 +182,7 @@ public: void AddCompileDefinition(std::string const& definition); void AddCompileOption(std::string const& option); void AddLinkOption(std::string const& option); - void AddLinkDirectory(std::string const& directory); + void AddLinkDirectory(std::string const& directory, bool before = false); /** Create a new imported target with the name and type given. */ cmTarget* AddImportedTarget(const std::string& name, diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 5160f51..f94e714 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -417,6 +417,33 @@ void cmStateDirectory::AppendLinkDirectoriesEntry( this->DirectoryState->LinkDirectoriesBacktraces, this->Snapshot_.Position->LinkDirectoriesPosition, vec, lfbt); } +void cmStateDirectory::PrependLinkDirectoriesEntry( + const std::string& vec, const cmListFileBacktrace& lfbt) +{ + std::vector<std::string>::iterator entryEnd = + this->DirectoryState->LinkDirectories.begin() + + this->Snapshot_.Position->LinkDirectoriesPosition; + + std::vector<std::string>::reverse_iterator rend = + this->DirectoryState->LinkDirectories.rend(); + std::vector<std::string>::reverse_iterator rbegin = + cmMakeReverseIterator(entryEnd); + rbegin = std::find(rbegin, rend, cmPropertySentinal); + + std::vector<std::string>::iterator entryIt = rbegin.base(); + std::vector<std::string>::iterator entryBegin = + this->DirectoryState->LinkDirectories.begin(); + + std::vector<cmListFileBacktrace>::iterator btIt = + this->DirectoryState->LinkDirectoriesBacktraces.begin() + + std::distance(entryBegin, entryIt); + + this->DirectoryState->LinkDirectories.insert(entryIt, vec); + this->DirectoryState->LinkDirectoriesBacktraces.insert(btIt, lfbt); + + this->Snapshot_.Position->LinkDirectoriesPosition = + this->DirectoryState->LinkDirectories.size(); +} void cmStateDirectory::SetLinkDirectories(const std::string& vec, const cmListFileBacktrace& lfbt) diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index 06345e2..e5f4d05 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -62,6 +62,8 @@ public: cmBacktraceRange GetLinkOptionsEntryBacktraces() const; void AppendLinkOptionsEntry(std::string const& vec, cmListFileBacktrace const& lfbt); + void PrependLinkDirectoriesEntry(std::string const& vec, + cmListFileBacktrace const& lfbt); void SetLinkOptions(std::string const& vec, cmListFileBacktrace const& lfbt); void ClearLinkOptions(); diff --git a/Tests/CMakeCommands/link_directories/CMakeLists.txt b/Tests/CMakeCommands/link_directories/CMakeLists.txt new file mode 100644 index 0000000..60c07b6 --- /dev/null +++ b/Tests/CMakeCommands/link_directories/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.12) + +project(link_directories LANGUAGES C) + + +link_directories(/A) +link_directories(BEFORE /B) + +set(CMAKE_LINK_DIRECTORIES_BEFORE ON) +link_directories(/C) + +get_directory_property(result LINK_DIRECTORIES) +if (NOT result MATCHES "/C;/B;/A") + message(SEND_ERROR "link_directories not populated the LINK_DIRECTORIES directory property") +endif() + + +add_executable(link_directories EXCLUDE_FROM_ALL LinkDirectoriesExe.c) + +get_target_property(result link_directories LINK_DIRECTORIES) +if (NOT result MATCHES "/C;/B;/A") + message(SEND_ERROR "link_directories not populated the LINK_DIRECTORIES target property") +endif() + + +add_library(imp UNKNOWN IMPORTED) +get_target_property(result imp LINK_DIRECTORIES) +if (result) + message(FATAL_ERROR "link_directories populated the LINK_DIRECTORIES target property") +endif() diff --git a/Tests/CMakeCommands/link_directories/LinkDirectoriesExe.c b/Tests/CMakeCommands/link_directories/LinkDirectoriesExe.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/CMakeCommands/link_directories/LinkDirectoriesExe.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4753aac..83349e3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2823,7 +2823,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ADD_TEST_MACRO(CMakeCommands.add_compile_definitions add_compile_definitions) ADD_TEST_MACRO(CMakeCommands.add_compile_options add_compile_options) ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) - ADD_TEST_MACRO(CMakeCommands.target_link_directories) ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories) ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions) ADD_TEST_MACRO(CMakeCommands.target_compile_options target_compile_options) @@ -2831,6 +2830,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ADD_TEST_MACRO(CMakeCommands.add_link_options) ADD_TEST_MACRO(CMakeCommands.target_link_options) + ADD_TEST_MACRO(CMakeCommands.link_directories) + ADD_TEST_MACRO(CMakeCommands.target_link_directories) # The cmake server-mode test requires python for a simple client. find_package(PythonInterp QUIET) |