Commit 61f1d989 authored by Evgeny Fimochkin's avatar Evgeny Fimochkin
Browse files

Merge branch 'master' of gitlab.kitware.com:selenorks/cmake

parents 6b8f9082 8e7922e3
Pipeline #180991 waiting for manual action with stages
in 30 minutes and 45 seconds
......@@ -20,6 +20,8 @@ SortUsingDeclarations: false
SpaceAfterTemplateKeyword: true
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^[<"]cmSTL\.hxx'
Priority: -2
- Regex: '^[<"]cmConfigure\.h'
Priority: -1
- Regex: '^<queue>'
......
......@@ -34,10 +34,12 @@
- build/Tests/CMake*/PseudoMemcheck/purify
- build/Tests/CMake*/PseudoMemcheck/memcheck_fail
- build/Tests/CMake*/PseudoMemcheck/BC
- build/Tests/CMake*/PseudoMemcheck/cuda-memcheck
- build/Tests/CMake*/PseudoMemcheck/valgrind.exe
- build/Tests/CMake*/PseudoMemcheck/purify.exe
- build/Tests/CMake*/PseudoMemcheck/memcheck_fail.exe
- build/Tests/CMake*/PseudoMemcheck/BC.exe
- build/Tests/CMake*/PseudoMemcheck/cuda-memcheck.exe
- build/Tests/CMake*/PseudoMemcheck/NoLog
- build/Tests/CMake*Lib/*LibTests
- build/Tests/CMake*Lib/*LibTests.exe
......
......@@ -108,6 +108,11 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
endif()
endif()
# Inform STL library header wrappers whether to use system versions.
configure_file(${CMake_SOURCE_DIR}/Utilities/std/cmSTL.hxx.in
${CMake_BINARY_DIR}/Utilities/cmSTL.hxx
@ONLY)
# set the internal encoding of CMake to UTF-8
set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8)
......
......@@ -10,7 +10,7 @@ Get a property.
DIRECTORY [<dir>] |
TARGET <target> |
SOURCE <source> |
[TARGET_DIRECTORY <target> | DIRECTORY <dir>] |
[DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
INSTALL <file> |
TEST <test> |
CACHE <entry> |
......@@ -31,18 +31,36 @@ It must be one of the following:
Scope defaults to the current directory but another
directory (already processed by CMake) may be named by the
full or relative path ``<dir>``.
See also the :command:`get_directory_property` command.
``TARGET``
Scope must name one existing target.
See also the :command:`get_target_property` command.
``SOURCE``
Scope must name one source file.
Scope must name one source file. By default, the source file's property
will be read from the current source directory's scope, but this can be
overridden with one of the following sub-options:
``DIRECTORY <dir>``
The source file property will be read from the ``<dir>`` directory's
scope. CMake must already know about that source directory, either by
having added it through a call to :command:`add_subdirectory` or ``<dir>``
being the top level source directory. Relative paths are treated as
relative to the current source directory.
``TARGET_DIRECTORY <target>``
The source file property will be read from the directory scope in which
``<target>`` was created (``<target>`` must therefore already exist).
See also the :command:`get_source_file_property` command.
``INSTALL``
Scope must name one installed file path.
``TEST``
Scope must name one existing test.
See also the :command:`get_test_property` command.
``CACHE``
Scope must name one cache entry.
......@@ -50,15 +68,6 @@ It must be one of the following:
``VARIABLE``
Scope is unique and does not accept a name.
In the ``SOURCE`` case, the queried source file scope can be changed by
specifying one of the additional options: ``DIRECTORY`` or ``TARGET_DIRECTORY``.
``DIRECTORY`` takes a path to a processed directory, and the source file property
will be read from that directory scope.
``TARGET_DIRECTORY`` takes the name of an existing target. The source file
property will be read from this target's directory scope.
The required ``PROPERTY`` option is immediately followed by the name of
the property to get. If the property is not set an empty value is
returned, although some properties support inheriting from a parent scope
......
......@@ -5,24 +5,33 @@ Get a property for a source file.
.. code-block:: cmake
get_source_file_property(VAR file [TARGET_DIRECTORY <target> | DIRECTORY <dir>] property)
get_source_file_property(<variable> <file>
[DIRECTORY <dir> | TARGET_DIRECTORY <target>]
<property>)
Gets a property from a source file. The value of the property is
stored in the variable ``VAR``. If the source property is not found, the
behavior depends on whether it has been defined to be an ``INHERITED`` property
or not (see :command:`define_property`). Non-inherited properties will set
``VAR`` to "NOTFOUND", whereas inherited properties will search the relevant
parent scope as described for the :command:`define_property` command and
if still unable to find the property, ``VAR`` will be set to an empty string.
The queried source file scope can be changed by specifying one of the
additional options: ``DIRECTORY`` or ``TARGET_DIRECTORY``.
``DIRECTORY`` takes a path to a processed directory, and the source file property
will be read from that directory scope.
``TARGET_DIRECTORY`` takes the name of an existing target. The source file
property will be read from this target's directory scope.
stored in the specified ``<variable>``. If the source property is not found,
the behavior depends on whether it has been defined to be an ``INHERITED``
property or not (see :command:`define_property`). Non-inherited properties
will set ``variable`` to ``NOTFOUND``, whereas inherited properties will search
the relevant parent scope as described for the :command:`define_property`
command and if still unable to find the property, ``variable`` will be set to
an empty string.
By default, the source file's property will be read from the current source
directory's scope, but this can be overridden with one of the following
sub-options:
``DIRECTORY <dir>``
The source file property will be read from the ``<dir>`` directory's
scope. CMake must already know about that source directory, either by
having added it through a call to :command:`add_subdirectory` or ``<dir>``
being the top level source directory. Relative paths are treated as
relative to the current source directory.
``TARGET_DIRECTORY <target>``
The source file property will be read from the directory scope in which
``<target>`` was created (``<target>`` must therefore already exist).
Use :command:`set_source_files_properties` to set property values. Source
file properties usually control how the file is built. One property that is
......
......@@ -9,13 +9,13 @@ Set a named property in a given scope.
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
SOURCE [<src1> ...]
[TARGET_DIRECTORY <target1> ...]
[DIRECTORY <dir1> ...] |
[DIRECTORY <dirs> ...] |
[TARGET_DIRECTORY <targets> ...]
INSTALL [<file1> ...] |
TEST [<test1> ...] |
CACHE [<entry1> ...] >
[APPEND] [APPEND_STRING]
PROPERTY <name> [value1 ...])
PROPERTY <name> [<value1> ...])
Sets one property on zero or more objects of a scope.
......@@ -35,17 +35,23 @@ It must be one of the following:
See also the :command:`set_target_properties` command.
``SOURCE``
Scope may name zero or more source files. Note that source
file properties are by default visible only to targets added in the same
directory (``CMakeLists.txt``).
The file properties can be made visible in a different directory by specifying
one or both of the additional options: ``TARGET_DIRECTORY`` and ``DIRECTORY``.
Scope may name zero or more source files. By default, source file properties
are only visible to targets added in the same directory (``CMakeLists.txt``).
Visibility can be set in other directory scopes using one or both of the
following sub-options:
``DIRECTORY <dirs>...``
The source file property will be set in each of the ``<dirs>``
directories' scopes. CMake must already know about each of these
source directories, either by having added them through a call to
:command:`add_subdirectory` or it being the top level source directory.
Relative paths are treated as relative to the current source directory.
``TARGET_DIRECTORY <targets>...``
The source file property will be set in each of the directory scopes
where any of the specified ``<targets>`` were created (the ``<targets>``
must therefore already exist).
``DIRECTORY`` takes a list of processed directories paths, and sets the file
properties in those directory scopes.
``TARGET_DIRECTORY`` takes a list of existing targets. The file
properties will be set in these targets' directory scopes.
See also the :command:`set_source_files_properties` command.
``INSTALL``
......
......@@ -5,29 +5,33 @@ Source files can have properties that affect how they are built.
.. code-block:: cmake
set_source_files_properties([file1 [file2 [...]]]
[TARGET_DIRECTORY <target1> ...]
[DIRECTORY <dir1> ...]
PROPERTIES prop1 value1
[prop2 value2 [...]])
set_source_files_properties(<files> ...
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...]
PROPERTIES <prop1> <value1>
[<prop2> <value2>] ...)
Sets properties associated with source files using a key/value paired
list.
Note that source file properties are by default visible only to
targets added in the same directory (``CMakeLists.txt``).
By default, source file properties are only visible to targets added in the
same directory (``CMakeLists.txt``). Visibility can be set in other directory
scopes using one or both of the following options:
The file properties can be made visible in a different directory by specifying
one or both of the additional options: ``TARGET_DIRECTORY`` and ``DIRECTORY``.
``DIRECTORY <dirs>...``
The source file properties will be set in each of the ``<dirs>``
directories' scopes. CMake must already know about each of these
source directories, either by having added them through a call to
:command:`add_subdirectory` or it being the top level source directory.
Relative paths are treated as relative to the current source directory.
``DIRECTORY`` takes a list of processed directories paths, and sets the file
properties in those directory scopes.
``TARGET_DIRECTORY`` takes a list of existing targets. The file
properties will be set in these targets' directory scopes.
``TARGET_DIRECTORY <targets>...``
The source file properties will be set in each of the directory scopes
where any of the specified ``<targets>`` were created (the ``<targets>``
must therefore already exist).
Use :command:`get_source_file_property` to get property values.
See also the :command:`set_property(SOURCE)` command.
See :ref:`Source File Properties` for the list of properties known
to CMake. Source file properties are visible only to targets added
in the same directory (``CMakeLists.txt``).
to CMake.
......@@ -35,6 +35,9 @@ Available features are:
* From ``C++14``:
* ``<cm/iomanip>``:
``cm::quoted``
* ``<cm/iterator>``:
``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``,
``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend``
......@@ -53,6 +56,9 @@ Available features are:
* ``<cm/algorithm>``:
``cm::clamp``
* ``cm/filesystem>``:
``cm::filesystem::path``
* ``<cm/iterator>``:
``cm::size``, ``cm::empty``, ``cm::data``
......
CTest
-----
* :manual:`ctest(1)` gained support for cuda-memcheck as ``CTEST_MEMORYCHECK_COMMAND``.
The different tools (memcheck, racecheck, synccheck, initcheck) supplied by
cuda-memcheck can be selected by setting the appropriate flags using the
``CTEST_MEMORYCHECK_COMMAND_OPTIONS`` variable.
The default flags are `--tool memcheck --leak-check full`.
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 18)
set(CMake_VERSION_PATCH 20200712)
set(CMake_VERSION_PATCH 20200714)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
......
......@@ -326,6 +326,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
xml.Attribute("Checker", "BoundsChecker");
break;
case cmCTestMemCheckHandler::CUDA_MEMCHECK:
xml.Attribute("Checker", "CudaMemcheck");
break;
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
xml.Attribute("Checker", "AddressSanitizer");
break;
......@@ -465,6 +468,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
} else if (testerName.find("BC") != std::string::npos) {
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
} else if (testerName.find("cuda-memcheck") != std::string::npos) {
this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
} else {
this->MemoryTesterStyle = cmCTestMemCheckHandler::UNKNOWN;
}
......@@ -485,6 +490,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTester =
this->CTest->GetCTestConfiguration("BoundsCheckerCommand");
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
} else if (cmSystemTools::FileExists(
this->CTest->GetCTestConfiguration("CudaMemcheckCommand"))) {
this->MemoryTester =
this->CTest->GetCTestConfiguration("CudaMemcheckCommand");
this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"AddressSanitizer") {
......@@ -528,6 +538,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
} else if (checkType == "DrMemory") {
this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
} else if (checkType == "CudaMemcheck") {
this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
}
}
if (this->MemoryTester.empty()) {
......@@ -553,6 +565,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
.empty()) {
memoryTesterOptions =
this->CTest->GetCTestConfiguration("DrMemoryCommandOptions");
} else if (!this->CTest->GetCTestConfiguration("CudaMemcheckCommandOptions")
.empty()) {
memoryTesterOptions =
this->CTest->GetCTestConfiguration("CudaMemcheckCommandOptions");
}
this->MemoryTesterOptions =
cmSystemTools::ParseArguments(memoryTesterOptions);
......@@ -686,6 +702,18 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterOptions.emplace_back("/M");
break;
}
case cmCTestMemCheckHandler::CUDA_MEMCHECK: {
// cuda-memcheck separates flags from arguments by spaces
if (this->MemoryTesterOptions.empty()) {
this->MemoryTesterOptions.emplace_back("--tool");
this->MemoryTesterOptions.emplace_back("memcheck");
this->MemoryTesterOptions.emplace_back("--leak-check");
this->MemoryTesterOptions.emplace_back("full");
}
this->MemoryTesterDynamicOptions.emplace_back("--log-file");
this->MemoryTesterDynamicOptions.push_back(this->MemoryTesterOutputFile);
break;
}
// these are almost the same but the env var used is different
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
case cmCTestMemCheckHandler::LEAK_SANITIZER:
......@@ -771,6 +799,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
return this->ProcessMemCheckSanitizerOutput(str, log, results);
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
return this->ProcessMemCheckBoundsCheckerOutput(str, log, results);
case cmCTestMemCheckHandler::CUDA_MEMCHECK:
return this->ProcessMemCheckCudaOutput(str, log, results);
default:
log.append("\nMemory checking style used was: ");
log.append("None that I know");
......@@ -1103,6 +1133,118 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
return defects == 0;
}
bool cmCTestMemCheckHandler::ProcessMemCheckCudaOutput(
const std::string& str, std::string& log, std::vector<int>& results)
{
std::vector<std::string> lines;
cmsys::SystemTools::Split(str, lines);
bool unlimitedOutput = false;
if (str.find("CTEST_FULL_OUTPUT") != std::string::npos ||
this->CustomMaximumFailedTestOutputSize == 0) {
unlimitedOutput = true;
}
std::string::size_type cc;
std::ostringstream ostr;
log.clear();
int defects = 0;
cmsys::RegularExpression memcheckLine("^========");
cmsys::RegularExpression leakExpr("== Leaked [0-9,]+ bytes at");
// list of matchers for output messages that contain variable content
// (addresses, sizes, ...) or can be shortened in general. the first match is
// used as a error name.
std::vector<cmsys::RegularExpression> matchers{
// API errors
"== Malloc/Free error encountered: (.*)",
"== Program hit error ([^ ]*).* on CUDA API call to",
"== Program hit ([^ ]*).* on CUDA API call to",
// memcheck
"== (Invalid .*) of size [0-9,]+",
// racecheck
"== .* (Potential .* hazard detected)", "== .* (Race reported)",
// synccheck
"== (Barrier error)",
// initcheck
"== (Uninitialized .* memory read)", "== (Unused memory)",
// generic error: ignore ERROR SUMMARY, CUDA-MEMCHECK and others
"== ([A-Z][a-z].*)"
};
std::vector<std::string::size_type> nonMemcheckOutput;
auto sttime = std::chrono::steady_clock::now();
cmCTestOptionalLog(this->CTest, DEBUG,
"Start test: " << lines.size() << std::endl, this->Quiet);
std::string::size_type totalOutputSize = 0;
for (cc = 0; cc < lines.size(); cc++) {
cmCTestOptionalLog(this->CTest, DEBUG,
"test line " << lines[cc] << std::endl, this->Quiet);
if (memcheckLine.find(lines[cc])) {
cmCTestOptionalLog(this->CTest, DEBUG,
"cuda-memcheck line " << lines[cc] << std::endl,
this->Quiet);
int failure = -1;
auto& line = lines[cc];
if (leakExpr.find(line)) {
failure = static_cast<int>(this->FindOrAddWarning("Memory leak"));
} else {
for (auto& matcher : matchers) {
if (matcher.find(line)) {
failure =
static_cast<int>(this->FindOrAddWarning(matcher.match(1)));
break;
}
}
}
if (failure >= 0) {
ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
if (results.empty() || unsigned(failure) > results.size() - 1) {
results.push_back(1);
} else {
results[failure]++;
}
defects++;
}
totalOutputSize += lines[cc].size();
ostr << lines[cc] << std::endl;
} else {
nonMemcheckOutput.push_back(cc);
}
}
// Now put all all the non cuda-memcheck output into the test output
// This should be last in case it gets truncated by the output
// limiting code
for (std::string::size_type i : nonMemcheckOutput) {
totalOutputSize += lines[i].size();
ostr << lines[i] << std::endl;
if (!unlimitedOutput &&
totalOutputSize >
static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) {
ostr << "....\n";
ostr << "Test Output for this test has been truncated see testing"
" machine logs for full output,\n";
ostr << "or put CTEST_FULL_OUTPUT in the output of "
"this test program.\n";
break; // stop the copy of output if we are full
}
}
cmCTestOptionalLog(this->CTest, DEBUG,
"End test (elapsed: "
<< cmDurationTo<unsigned int>(
std::chrono::steady_clock::now() - sttime)
<< "s)" << std::endl,
this->Quiet);
log = ostr.str();
this->DefectCount += defects;
return defects == 0;
}
// PostProcessTest memcheck results
void cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res, int test)
{
......
......@@ -46,6 +46,7 @@ private:
DRMEMORY,
BOUNDS_CHECKER,
// checkers after here do not use the standard error list
CUDA_MEMCHECK,
ADDRESS_SANITIZER,
LEAK_SANITIZER,
THREAD_SANITIZER,
......@@ -137,6 +138,8 @@ private:
std::vector<int>& results);
bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log,
std::vector<int>& results);
bool ProcessMemCheckCudaOutput(const std::string& str, std::string& log,
std::vector<int>& results);
bool ProcessMemCheckSanitizerOutput(const std::string& str, std::string& log,
std::vector<int>& results);
bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
......
......@@ -63,3 +63,8 @@ if(CMake_HAVE_CXX_MAKE_UNIQUE)
set(CMake_HAVE_CXX_UNIQUE_PTR 1)
endif()
cm_check_cxx_feature(unique_ptr)
if (NOT CMAKE_CXX_STANDARD LESS "17")
cm_check_cxx_feature(filesystem)
else()
set(CMake_HAVE_CXX_FILESYSTEM FALSE)
endif()
#include <filesystem>
int main()
{
std::filesystem::path p1("/a/b/c");
std::filesystem::path p2("/a/b/c");
return p1 == p2 ? 0 : 1;
}
......@@ -849,31 +849,31 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
{
// Get possible library name prefixes.
cmMakefile* mf = this->Makefile;
this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
// Import library names should be matched and treated as shared
// libraries for the purposes of linking.
this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
LinkShared);
this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
LinkStatic);
this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
LinkShared);
this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
LinkUnknown);
if (const char* linkSuffixes =
mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
std::vector<std::string> linkSuffixVec = cmExpandedList(linkSuffixes);
for (std::string const& i : linkSuffixVec) {
this->AddLinkExtension(i.c_str(), LinkUnknown);
this->AddLinkExtension(i, LinkUnknown);
}
}
if (const char* sharedSuffixes =
mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes);
for (std::string const& i : sharedSuffixVec) {
this->AddLinkExtension(i.c_str(), LinkShared);
this->AddLinkExtension(i, LinkShared);
}
}
......@@ -903,7 +903,7 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
#endif
this->ExtractAnyLibraryName.compile(reg_any.c_str());
this->ExtractAnyLibraryName.compile(reg_any);
// Create a regex to match static library names.
if (!this->StaticLinkExtensions.empty()) {
......@@ -912,7 +912,7 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
#endif
this->ExtractStaticLibraryName.compile(reg_static.c_str());
this->ExtractStaticLibraryName.compile(reg_static);
}
// Create a regex to match shared library names.
......@@ -924,20 +924,21 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
#endif
this->ExtractSharedLibraryName.compile(reg_shared.c_str());
this->ExtractSharedLibraryName.compile(reg_shared);
}
}
void cmComputeLinkInformation::AddLinkPrefix(const char* p)
void cmComputeLinkInformation::AddLinkPrefix(std::string const& p)
{
if (p && *p) {
if (!p.empty()) {
this->LinkPrefixes.insert(p);
}
}
void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
void cmComputeLinkInformation::AddLinkExtension(std::string const& e,
LinkType type)
{
if (e && *e) {
if (!e.empty()) {
if (type == LinkStatic) {
this->StaticLinkExtensions.emplace_back(e);
}
......@@ -962,7 +963,7 @@ std::string cmComputeLinkInformation::CreateExtensionRegex(