mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 05:40:54 -06:00
ENH: Implement linking with paths to library files instead of -L and -l separation. See bug #3832
- This is purely an implementation improvement. No interface has changed.
- Create cmComputeLinkInformation class
- Move and re-implement logic from:
cmLocalGenerator::ComputeLinkInformation
cmOrderLinkDirectories
- Link libraries to targets with their full path (if it is known)
- Dirs specified with link_directories command still added with -L
- Make link type specific to library names without paths
(name libfoo.a without path becomes -Wl,-Bstatic -lfoo)
- Make directory ordering specific to a runtime path computation feature
(look for conflicting SONAMEs instead of library names)
- Implement proper rpath support on HP-UX and AIX.
This commit is contained in:
@@ -13,7 +13,6 @@ extern "C" {
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmDynamicLoader.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmOrderLinkDirectories.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include <cmsys/DynamicLoader.hxx>
|
||||
#else
|
||||
@@ -69,99 +68,6 @@ void cmPassed(const char* Message, const char* m2="")
|
||||
#endif
|
||||
|
||||
#ifdef COMPLEX_TEST_CMAKELIB
|
||||
// Here is a stupid function that tries to use std::string methods
|
||||
// so that the dec cxx compiler will instantiate the stuff that
|
||||
// we are using from the CMakeLib library....
|
||||
bool TestLibraryOrder(bool shouldFail)
|
||||
{
|
||||
std::string Adir = std::string(BINARY_DIR) + std::string("/A");
|
||||
std::string Bdir = std::string(BINARY_DIR) + std::string("/B");
|
||||
std::string Cdir = std::string(BINARY_DIR) + std::string("/C");
|
||||
#ifdef _WIN32
|
||||
// Avoid case problems for windows paths.
|
||||
if(Adir[0] >= 'A' && Adir[0] <= 'Z') { Adir[0] += 'a' - 'A'; }
|
||||
if(Bdir[0] >= 'A' && Bdir[0] <= 'Z') { Bdir[0] += 'a' - 'A'; }
|
||||
if(Cdir[0] >= 'A' && Cdir[0] <= 'Z') { Cdir[0] += 'a' - 'A'; }
|
||||
Adir = cmSystemTools::GetActualCaseForPath(Adir.c_str());
|
||||
Bdir = cmSystemTools::GetActualCaseForPath(Bdir.c_str());
|
||||
Cdir = cmSystemTools::GetActualCaseForPath(Cdir.c_str());
|
||||
#endif
|
||||
|
||||
if(!shouldFail)
|
||||
{
|
||||
std::string rm = Bdir;
|
||||
rm += "/libA.a";
|
||||
cmSystemTools::RemoveFile(rm.c_str());
|
||||
}
|
||||
std::vector<std::string> linkLibraries;
|
||||
std::vector<std::string> linkDirectories;
|
||||
linkDirectories.push_back(Adir);
|
||||
linkDirectories.push_back(Bdir);
|
||||
linkDirectories.push_back(Cdir);
|
||||
linkDirectories.push_back("/lib/extra/stuff");
|
||||
Adir += "/libA.a";
|
||||
Bdir += "/libB.a";
|
||||
Cdir += "/libC.a";
|
||||
linkLibraries.push_back(Adir);
|
||||
linkLibraries.push_back(Bdir);
|
||||
linkLibraries.push_back(Cdir);
|
||||
linkLibraries.push_back("-lm");
|
||||
std::vector<cmStdString> sortedpaths;
|
||||
std::vector<cmStdString> linkItems;
|
||||
cmOrderLinkDirectories orderLibs;
|
||||
orderLibs.DebugOn();
|
||||
orderLibs.AddLinkExtension(".so");
|
||||
orderLibs.AddLinkExtension(".a");
|
||||
orderLibs.AddLinkPrefix("lib");
|
||||
cmTargetManifest manifest;
|
||||
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
|
||||
manifest, "");
|
||||
bool ret = orderLibs.DetermineLibraryPathOrder();
|
||||
if(!ret)
|
||||
{
|
||||
std::cout << orderLibs.GetWarnings() << "\n";
|
||||
}
|
||||
orderLibs.GetLinkerInformation(sortedpaths, linkItems);
|
||||
std::cout << "Sorted Link Paths:\n";
|
||||
for(std::vector<cmStdString>::iterator i = sortedpaths.begin();
|
||||
i != sortedpaths.end(); ++i)
|
||||
{
|
||||
std::cout << *i << "\n";
|
||||
}
|
||||
std::cout << "Link Items: \n";
|
||||
for(std::vector<cmStdString>::iterator i = linkItems.begin();
|
||||
i != linkItems.end(); ++i)
|
||||
{
|
||||
std::cout << *i << "\n";
|
||||
}
|
||||
if(!(linkItems[0] == "A" &&
|
||||
linkItems[1] == "B" &&
|
||||
linkItems[2] == "C" &&
|
||||
linkItems[3] == "-lm" ))
|
||||
{
|
||||
std::cout << "fail because link items should be A B C -lm and the are not\n";
|
||||
return shouldFail;
|
||||
}
|
||||
|
||||
|
||||
// if this is not the fail test then the order should be f B C A
|
||||
if(!shouldFail)
|
||||
{
|
||||
char order[5];
|
||||
order[4] = 0;
|
||||
for(int i =0; i < 4; ++i)
|
||||
{
|
||||
order[i] = sortedpaths[i][sortedpaths[i].size()-1];
|
||||
}
|
||||
if(!(strcmp(order, "fBCA") == 0 || strcmp(order, "BCAf") == 0))
|
||||
{
|
||||
std::cout << "fail because order should be /lib/extra/stuff B C A and it is not\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void TestAndRemoveFile(const char* filename)
|
||||
@@ -286,6 +192,9 @@ void TestCMGeneratedFileSTream()
|
||||
}
|
||||
#endif
|
||||
|
||||
// Here is a stupid function that tries to use std::string methods
|
||||
// so that the dec cxx compiler will instantiate the stuff that
|
||||
// we are using from the CMakeLib library....
|
||||
void ForceStringUse()
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
@@ -1283,27 +1192,6 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef COMPLEX_TEST_CMAKELIB
|
||||
// first run with shouldFail = true, this will
|
||||
// run with A B C as set by the CMakeList.txt file.
|
||||
if(!TestLibraryOrder(true))
|
||||
{
|
||||
cmPassed("CMake cmOrderLinkDirectories failed when it should.");
|
||||
}
|
||||
else
|
||||
{
|
||||
cmFailed("CMake cmOrderLinkDirectories failed to fail when given an impossible set of paths.");
|
||||
}
|
||||
// next run with shouldPass = true, this will
|
||||
// run with B/libA.a removed and should create the order
|
||||
// B C A
|
||||
if(TestLibraryOrder(false))
|
||||
{
|
||||
cmPassed("CMake cmOrderLinkDirectories worked.");
|
||||
}
|
||||
else
|
||||
{
|
||||
cmFailed("CMake cmOrderLinkDirectories failed.");
|
||||
}
|
||||
// Test the generated file stream.
|
||||
TestCMGeneratedFileSTream();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user