| @@ -20,8 +20,14 @@ void link_executable_plan::link(build_env_ref env, const library_plan& lib) cons | |||
| // Build up the link command | |||
| link_exe_spec spec; | |||
| spec.output = calc_executable_path(env); | |||
| spec.inputs = _input_libs; | |||
| dds_log(debug, "Performing link for {}", spec.output.string()); | |||
| // The main object should be a linker input, of course. | |||
| auto main_obj = _main_compile.calc_object_file_path(env); | |||
| dds_log(trace, "Add entry point object file: {}", main_obj.string()); | |||
| spec.inputs.push_back(std::move(main_obj)); | |||
| for (const lm::usage& links : _links) { | |||
| dds_log(trace, " - Link with: {}/{}", links.name, links.namespace_); | |||
| extend(spec.inputs, env.ureqs.link_paths(links)); | |||
| @@ -36,17 +42,6 @@ void link_executable_plan::link(build_env_ref env, const library_plan& lib) cons | |||
| dds_log(trace, "Executable has no corresponding archive library input"); | |||
| } | |||
| // The main object should be a linker input, of course. | |||
| auto main_obj = _main_compile.calc_object_file_path(env); | |||
| dds_log(trace, "Add entry point object file: {}", main_obj.string()); | |||
| spec.inputs.push_back(std::move(main_obj)); | |||
| // Linker inputs are order-dependent in some cases. The top-most input should appear first, and | |||
| // its dependencies should appear later. Because of the way inputs were generated, they appear | |||
| // sorted with the dependencies coming earlier than the dependees. We can simply reverse the | |||
| // order and linking will work. | |||
| std::reverse(spec.inputs.begin(), spec.inputs.end()); | |||
| // Do it! | |||
| const auto link_command | |||
| = env.toolchain.create_link_executable_command(spec, dds::fs::current_path(), env.knobs); | |||
| @@ -27,8 +27,6 @@ struct test_failure { | |||
| * single source file defines the entry point and some set of linker inputs. | |||
| */ | |||
| class link_executable_plan { | |||
| /// The linker inputs that should be linked into the executable | |||
| std::vector<fs::path> _input_libs; | |||
| /// Usage requirements for this executable | |||
| std::vector<lm::usage> _links; | |||
| /// The compilation plan for the entry-point source file | |||
| @@ -41,19 +39,16 @@ class link_executable_plan { | |||
| public: | |||
| /** | |||
| * Create a new instance | |||
| * @param in_libs Linker inputs for the executable | |||
| * @param links The library identifiers that the executable should link with | |||
| * @param cfp The file compilation that defines the entrypoint of the application | |||
| * @param out_subdir The subdirectory of the build root in which the executable should be placed | |||
| * @param name_ The name of the executable | |||
| */ | |||
| link_executable_plan(std::vector<fs::path> in_libs, | |||
| std::vector<lm::usage> links, | |||
| link_executable_plan(std::vector<lm::usage> links, | |||
| compile_file_plan cfp, | |||
| path_ref out_subdir, | |||
| std::string name_) | |||
| : _input_libs(std::move(in_libs)) | |||
| , _links(std::move(links)) | |||
| : _links(std::move(links)) | |||
| , _main_compile(std::move(cfp)) | |||
| , _out_subdir(out_subdir) | |||
| , _name(std::move(name_)) {} | |||
| @@ -100,10 +100,6 @@ library_plan library_plan::create(const library_root& lib, | |||
| extend(links, lib.manifest().uses); | |||
| extend(links, lib.manifest().links); | |||
| // Linker inputs for tests may contain additional code for test execution | |||
| std::vector<fs::path> link_libs; | |||
| std::vector<fs::path> test_link_libs = params.test_link_files; | |||
| // There may also be additional usage requirements for tests | |||
| auto test_rules = compile_rules.clone(); | |||
| auto test_links = links; | |||
| @@ -114,6 +110,14 @@ library_plan library_plan::create(const library_root& lib, | |||
| std::vector<link_executable_plan> link_executables; | |||
| for (const source_file& source : ranges::views::concat(app_sources, test_sources)) { | |||
| const bool is_test = source.kind == source_kind::test; | |||
| if (is_test && !params.build_tests) { | |||
| // This is a test, but we don't want to build tests | |||
| continue; | |||
| } | |||
| if (!is_test && !params.build_apps) { | |||
| // This is an app, but we don't want to build apps | |||
| continue; | |||
| } | |||
| // Pick a subdir based on app/test | |||
| const auto subdir_base = is_test ? params.out_subdir / "test" : params.out_subdir; | |||
| // Put test/app executables in a further subdirectory based on the source file path | |||
| @@ -121,11 +125,9 @@ library_plan library_plan::create(const library_root& lib, | |||
| // Pick compile rules based on app/test | |||
| auto rules = is_test ? test_rules : compile_rules; | |||
| // Pick input libs based on app/test | |||
| auto& exe_link_libs = is_test ? test_link_libs : link_libs; | |||
| auto& exe_links = is_test ? test_links : links; | |||
| auto& exe_links = is_test ? test_links : links; | |||
| // TODO: Apps/tests should only see the _public_ include dir, not both | |||
| auto exe = link_executable_plan{exe_link_libs, | |||
| exe_links, | |||
| auto exe = link_executable_plan{exe_links, | |||
| compile_file_plan(rules, | |||
| source, | |||
| qual_name, | |||
| @@ -30,8 +30,6 @@ struct library_build_params { | |||
| /// Directories that should be on the #include search path when compiling tests | |||
| std::vector<fs::path> test_include_dirs; | |||
| /// Files that should be added as inputs when linking test executables | |||
| std::vector<fs::path> test_link_files; | |||
| /// Libraries that are used by tests | |||
| std::vector<lm::usage> test_uses; | |||