summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2024-05-18 16:31:14 +0200
committerRoland Reichwein <mail@reichwein.it>2024-05-18 16:31:14 +0200
commitf857007dbb6a0a26a6828017da64540eda452fbf (patch)
treea2fc22abb236c6f07a9b9425a87b18f5f2e189f8
parent8a4dfbbbe76a2aef35427b7915d6e28bab165c43 (diff)
Link different kinds of libs
-rw-r--r--Builder.cpp6
-rw-r--r--Builder.h4
-rw-r--r--LanguageSettings.cpp14
-rw-r--r--LanguageSettings.h8
-rw-r--r--file.cpp13
-rw-r--r--file.h1
-rw-r--r--test-ymake.cpp2
7 files changed, 36 insertions, 12 deletions
diff --git a/Builder.cpp b/Builder.cpp
index 4850be3..74fbcdf 100644
--- a/Builder.cpp
+++ b/Builder.cpp
@@ -179,7 +179,7 @@ Builder::Builder(const pt::ptree& ptree, const std::string& target):
_all_targets{get_all_targets(ptree, target)},
_all_objects{get_all_objects(ptree, target)},
_include_paths{get_subelements<fs::path>(ptree, target, "includepath")},
- _link_libs{get_subelements<std::string>(ptree, target, "linklib")}
+ _link_libs{get_subelements<fs::path>(ptree, target, "linklib")}
{
// intentionally defer creation of _dependencies to build()
// to prevent creation of .d files in clean()
@@ -204,7 +204,7 @@ std::vector<fs::path> Builder::dependencies_of(const fs::path& p) const
}
}
-std::vector<std::string> Builder::link_libs_of(const fs::path& p) const
+std::vector<fs::path> Builder::link_libs_of(const fs::path& p) const
{
try {
return _link_libs.at(p);
@@ -336,7 +336,7 @@ void Builder::build_file(const fs::path& p) {
} else {
// link
std::vector<fs::path> objects{dependencies_of(p)};
- std::vector<std::string> link_libs{link_libs_of(p)};
+ std::vector<fs::path> link_libs{link_libs_of(p)};
command = _lang.getLinkCommand(p, objects, link_libs);
}
diff --git a/Builder.h b/Builder.h
index bd11599..523175a 100644
--- a/Builder.h
+++ b/Builder.h
@@ -27,7 +27,7 @@ private:
std::vector<std::filesystem::path> dependencies_of(const std::filesystem::path& p) const;
std::vector<std::filesystem::path> include_paths_of_object(const std::filesystem::path& p) const;
std::filesystem::path target_from_object(const std::filesystem::path& object) const;
- std::vector<std::string> link_libs_of(const std::filesystem::path& p) const;
+ std::vector<std::filesystem::path> link_libs_of(const std::filesystem::path& p) const;
bool is_outdated(const std::filesystem::path& p) const;
bool is_outdated(const std::filesystem::path& p, const std::vector<std::filesystem::path> &dependencies) const;
std::vector<std::filesystem::path> make_depfile_from(const std::filesystem::path& p) const;
@@ -45,7 +45,7 @@ private:
std::vector<std::filesystem::path> _all_objects;
std::unordered_map<std::filesystem::path, std::vector<std::filesystem::path>> _dependencies;
std::unordered_map<std::filesystem::path, std::vector<std::filesystem::path>> _include_paths;
- std::unordered_map<std::filesystem::path, std::vector<std::string>> _link_libs;
+ std::unordered_map<std::filesystem::path, std::vector<std::filesystem::path>> _link_libs;
LanguageSettings _lang;
ProcessRunner _runner;
diff --git a/LanguageSettings.cpp b/LanguageSettings.cpp
index 5eae731..5bec072 100644
--- a/LanguageSettings.cpp
+++ b/LanguageSettings.cpp
@@ -72,7 +72,7 @@ std::string LanguageSettings::getCompileCommand(const std::filesystem::path& tar
std::string LanguageSettings::getLinkCommand(const std::filesystem::path& target,
const std::vector<std::filesystem::path> &inputs,
- const std::vector<std::string>& link_libs) const
+ const std::vector<std::filesystem::path>& link_libs) const
{
std::string input_string{std::accumulate(inputs.begin(), inputs.end(), std::string{},
[](const std::string& sum, const fs::path& p){ return sum + " " + p.string(); })};
@@ -88,8 +88,16 @@ std::string LanguageSettings::getLinkCommand(const std::filesystem::path& target
std::string LDFLAGS_add{is_dynamic_lib(target) ? fmt::format(" -shared -Wl,-soname,{}",
soname_shorter(target.string()).string()) : ""s};
- std::string link_libs_string{std::accumulate(link_libs.begin(), link_libs.end(), std::string(),
- [](const std::string& sum, const std::string& i){ return sum + " -l" + i; })};
+ std::string link_libs_string;
+ for (const auto& i: link_libs) {
+ if (is_static_lib(i.string())) {
+ input_string += " " + i.string();
+ } else if (is_dynamic_lib(i.string()) || is_dynamic_lib_link(i.string())) {
+ input_string += " -L" + i.parent_path().string() + " -l" + dynamic_lib_name(i);
+ } else { // link external dynamic lib, e.g. "fmt"
+ link_libs_string += " -l" + i.string();
+ }
+ }
// link: $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@
return fmt::format("{}{}{}{}{}{}{} -o {}",
diff --git a/LanguageSettings.h b/LanguageSettings.h
index 0378d81..83eaa09 100644
--- a/LanguageSettings.h
+++ b/LanguageSettings.h
@@ -10,13 +10,13 @@ public:
LanguageSettings();
std::string getCompileCommand(const std::filesystem::path& target,
- const std::filesystem::path &source,
+ const std::filesystem::path& source,
const std::filesystem::path& build,
const std::vector<std::filesystem::path>& includepaths) const;
std::string getLinkCommand(const std::filesystem::path& target,
- const std::vector<std::filesystem::path> &inputs,
- const std::vector<std::string>& link_libs) const;
- std::string getDepCommand(const std::filesystem::path& target, const std::filesystem::path &source) const;
+ const std::vector<std::filesystem::path>& inputs,
+ const std::vector<std::filesystem::path>& link_libs) const;
+ std::string getDepCommand(const std::filesystem::path& target, const std::filesystem::path& source) const;
private:
std::string CXX;
diff --git a/file.cpp b/file.cpp
index 31695e5..b5cbe36 100644
--- a/file.cpp
+++ b/file.cpp
@@ -94,6 +94,19 @@ std::filesystem::path soname_short(const std::filesystem::path& p)
return result;
}
+// e.g.
+// subdir1/libxyz.so.1.2.3 -> xyz
+// libabc.so -> abc
+// file1.so.1 -> file1
+std::string dynamic_lib_name(const std::filesystem::path& p)
+{
+ std::string result {p.stem().string()};
+ if (result.substr(0, 3) == "lib") {
+ result = result.substr(3);
+ }
+ return result;
+}
+
bool is_static_lib(const std::filesystem::path& p)
{
return p.extension() == ".a";
diff --git a/file.h b/file.h
index a49825c..fbab148 100644
--- a/file.h
+++ b/file.h
@@ -15,6 +15,7 @@ bool is_dynamic_lib_link(const std::filesystem::path& p);
bool is_static_lib(const std::filesystem::path& p);
std::filesystem::path soname_shorter(const std::filesystem::path& p);
std::filesystem::path soname_short(const std::filesystem::path& p);
+std::string dynamic_lib_name(const std::filesystem::path& p);
// removes initial "./"
std::filesystem::path simplified_path(const std::filesystem::path& p);
diff --git a/test-ymake.cpp b/test-ymake.cpp
index bf59bbc..e5371f7 100644
--- a/test-ymake.cpp
+++ b/test-ymake.cpp
@@ -668,6 +668,8 @@ TEST_F(ymakeTest, build_one_dynamic_lib)
// use dynamic lib
// use static lib from subdir
// use dynamic lib from subdir
+// use static lib from subdir in subdir
+// use dynamic lib from subdir in subdir
TEST_F(yscanTest, no_cpp_file)
{