diff options
author | Roland Reichwein <mail@reichwein.it> | 2024-05-31 15:21:50 +0200 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2024-05-31 15:21:50 +0200 |
commit | 92be2196d6515f854295b0b830ad7dd4b97bb956 (patch) | |
tree | 41b77d8c2399d3fe2216cc1b98701aaf5446830b | |
parent | f857007dbb6a0a26a6828017da64540eda452fbf (diff) |
Build static libs as dependencies
-rw-r--r-- | Builder.cpp | 10 | ||||
-rw-r--r-- | test-ymake.cpp | 145 |
2 files changed, 149 insertions, 6 deletions
diff --git a/Builder.cpp b/Builder.cpp index 74fbcdf..6fd4f3c 100644 --- a/Builder.cpp +++ b/Builder.cpp @@ -298,8 +298,12 @@ std::unordered_map<fs::path, std::vector<fs::path>> Builder::get_dependencies(co for (const auto& element: ptree.get_child(topelement)) { if (is_match(element, _target)) { // add target - fs::path target{get_target(element.second)}; - dependencies.emplace(target, get_objects(element.second)); + const pt::ptree& list{element.second}; + fs::path target{get_target(list)}; + std::vector<fs::path> deps{get_objects(list)}; + std::vector<fs::path> link_libs{link_libs_of(target)}; + std::copy(link_libs.begin(), link_libs.end(), std::back_inserter(deps)); + dependencies.emplace(target, deps); // add dynamic lib links if (is_dynamic_lib(target)) { @@ -309,7 +313,7 @@ std::unordered_map<fs::path, std::vector<fs::path>> Builder::get_dependencies(co if (include_sources) { // add source dependencies of *.o - std::vector<fs::path> sources{get_sources(element.second)}; + std::vector<fs::path> sources{get_sources(list)}; for (const auto& p: sources) { fs::path p_obj{p}; p_obj.replace_extension("o"); diff --git a/test-ymake.cpp b/test-ymake.cpp index e5371f7..8184bcf 100644 --- a/test-ymake.cpp +++ b/test-ymake.cpp @@ -113,6 +113,10 @@ TEST_F(ymakeTest, build_one_cpp) EXPECT_EQ(result, 0); EXPECT_EQ(output.size(), 2); // compile, link + + result = run_command("./hello", output); + EXPECT_EQ(result, 0); + EXPECT_EQ(output.size(), 0); // run } TEST_F(ymakeTest, build_one_cpp_compile_error) @@ -549,6 +553,84 @@ TEST_F(ymakeTest, multiple_dirs) EXPECT_EQ(output.size(), 0); } +TEST_F(ymakeTest, multiple_dirs_nested) +{ + create_file("hello.cpp", R"(int main(int argc, char* argv[]) +{ + return 0; +})"); + + create_file("YMakefile", R"( +<ymake> + <build> + <name>hello</name> + <source>hello.cpp</source> + </build> +</ymake> +)"); + + fs::create_directory("subdir1"); + + create_file("subdir1/second.cpp", R"(int main(int argc, char* argv[]) +{ + return 0; +})"); + + create_file("subdir1/YMakefile", R"( +<ymake> + <build> + <name>second</name> + <source>second.cpp</source> + </build> +</ymake> +)"); + + fs::create_directory("subdir1/subdir2"); + + create_file("subdir1/subdir2/third.cpp", R"(int main(int argc, char* argv[]) +{ + return 0; +})"); + + create_file("subdir1/subdir2/YMakefile", R"( +<ymake> + <build> + <name>third</name> + <source>third.cpp</source> + </build> +</ymake> +)"); + + std::vector<std::string> output; + int result = run_command("../ymake", output); + EXPECT_EQ(result, 0); + EXPECT_EQ(output.size(), 6); // 3x compile + link + + EXPECT_TRUE(fs::exists("hello")); + EXPECT_TRUE(fs::exists("hello.o")); + EXPECT_TRUE(fs::exists("hello.d")); + + EXPECT_TRUE(fs::exists("subdir1/second")); + EXPECT_TRUE(fs::exists("subdir1/second.o")); + EXPECT_TRUE(fs::exists("subdir1/second.d")); + + EXPECT_TRUE(fs::exists("subdir1/subdir2/third")); + EXPECT_TRUE(fs::exists("subdir1/subdir2/third.o")); + EXPECT_TRUE(fs::exists("subdir1/subdir2/third.d")); + + result = run_command("../ymake", output); + EXPECT_EQ(result, 0); + EXPECT_EQ(output.size(), 1); // everything up to date + + result = run_command("../ymake clean", output); + EXPECT_EQ(result, 0); + EXPECT_EQ(output.size(), 9); // hello hello.o hello.d second second.o second.d third.* + + result = run_command("../ymake clean", output); + EXPECT_EQ(result, 0); + EXPECT_EQ(output.size(), 0); +} + TEST_F(ymakeTest, build_one_static_lib) { create_file("hello.cpp", R"(int maine(int argc, char* argv[]) @@ -663,8 +745,67 @@ TEST_F(ymakeTest, build_one_dynamic_lib) ASSERT_EQ(output.size(), 0); } +TEST_F(ymakeTest, use_one_static_lib) +{ + create_file("YMakefile", R"( +<ymake> + <build> + <name>hello.a</name> + <source>hello.cpp</source> + </build> + <build> + <name>runmain</name> + <source>runmain.cpp</source> + <linklib>hello.a</linklib> + </build> +</ymake> +)"); + + create_file("hello.cpp", R"(#include "hello.h" +#include <iostream> +int hello() +{ + std::cout << "Hello." << std::endl; + return 0; +})"); + + create_file("hello.h", R"(#pragma once +extern int hello(); +)"); + + create_file("runmain.cpp", R"(#include "hello.h" +int main(int argc, char* argv[]) +{ + hello(); + return 0; +})"); + + std::vector<std::string> output; + int result = run_command("../ymake", output); + EXPECT_EQ(result, 0); + ASSERT_EQ(output.size(), 4); // compile, link, compile, link + + EXPECT_TRUE(fs::exists("hello.o")); + EXPECT_TRUE(fs::exists("hello.a")); + EXPECT_TRUE(fs::exists("runmain.o")); + EXPECT_TRUE(fs::exists("runmain")); + + result = run_command("./runmain", output); + EXPECT_EQ(result, 0); + ASSERT_EQ(output.size(), 1); + EXPECT_EQ(output[0], "Hello."); + + result = run_command("../ymake clean", output); + EXPECT_EQ(result, 0); + ASSERT_EQ(output.size(), 6); // hello.o, hello.d, hello.a, runmain.o, runmain.d, runmain + + EXPECT_TRUE(!fs::exists("hello.o")); + EXPECT_TRUE(!fs::exists("hello.a")); + EXPECT_TRUE(!fs::exists("runmain.o")); + EXPECT_TRUE(!fs::exists("runmain")); +} + // TODO: -// use static lib // use dynamic lib // use static lib from subdir // use dynamic lib from subdir @@ -786,5 +927,3 @@ TEST_F(yscanTest, unrelated_files) )"); } -// TODO: test multiple directories - |