summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Builder.cpp10
-rw-r--r--test-ymake.cpp145
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
-