diff --git a/src/project_parser.cpp b/src/project_parser.cpp index 22d9e7f..218b44c 100644 --- a/src/project_parser.cpp +++ b/src/project_parser.cpp @@ -597,6 +597,38 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p t.optional("link-libraries", target.link_libraries); t.optional("private-link-libraries", target.private_link_libraries); + // Add support for relative paths for (private-)link-libraries + const auto fix_relative_paths = [&name, &path](ConditionVector &libraries, const char *key) { + for (const auto &library_entries : libraries) { + for (auto &library_path : libraries[library_entries.first]) { + // Skip processing paths with potential CMake macros in them (this check isn't perfect) + // https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#variable-references + if ((library_path.find("${") != std::string::npos || library_path.find("$ENV{") != std::string::npos || + library_path.find("$CACHE{") != std::string::npos) && + library_path.find('}') != std::string::npos) { + continue; + } + + // Skip paths that don't contain backwards or forwards slashes + if (library_path.find_first_of(R"(\/)") == std::string::npos) { + continue; + } + + // Check if the new file path exists, otherwise emit an error + const auto expected_library_file_path = fs::path{path} / library_path; + if (!fs::exists(expected_library_file_path)) { + throw std::runtime_error("Attempted to link against a library file that doesn't exist for target \"" + name + "\" in \"" + + key + "\": " + library_path); + } + + // Prepend ${CMAKE_CURRENT_SOURCE_DIR} to the path + library_path.insert(0, "${CMAKE_CURRENT_SOURCE_DIR}/"); + } + } + }; + fix_relative_paths(target.link_libraries, "link-libraries"); + fix_relative_paths(target.private_link_libraries, "private-link-libraries"); + t.optional("link-options", target.link_options); t.optional("private-link-options", target.private_link_options); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 448180a..22aa4b4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -109,3 +109,16 @@ add_test( "$" build ) + +if(WIN32) # windows + add_test( + NAME + relative-paths + WORKING_DIRECTORY + "${CMAKE_CURRENT_LIST_DIR}/relative-paths" + COMMAND + "$" + build + ) + +endif() diff --git a/tests/cmake.toml b/tests/cmake.toml index 6d20721..338b37d 100644 --- a/tests/cmake.toml +++ b/tests/cmake.toml @@ -57,4 +57,11 @@ arguments = ["build"] name = "compile-options" working-directory = "compile-options" command = "$" -arguments = ["build"] \ No newline at end of file +arguments = ["build"] + +[[test]] +condition = "windows" +name = "relative-paths" +working-directory = "relative-paths" +command = "$" +arguments = ["build"] diff --git a/tests/relative-paths/cmake.toml b/tests/relative-paths/cmake.toml new file mode 100644 index 0000000..d029bbe --- /dev/null +++ b/tests/relative-paths/cmake.toml @@ -0,0 +1,11 @@ +[project] +name = "relative-paths" + +[target.test-library] +type = "static" +sources = ["src/library-code.cpp"] + +[target.example] +type = "executable" +sources = ["src/main.cpp"] +windows.link-libraries = ["libs/test-library-x64-Release.lib"] diff --git a/tests/relative-paths/libs/test-library-x64-Release.lib b/tests/relative-paths/libs/test-library-x64-Release.lib new file mode 100644 index 0000000..cc5017a Binary files /dev/null and b/tests/relative-paths/libs/test-library-x64-Release.lib differ diff --git a/tests/relative-paths/src/library-code.cpp b/tests/relative-paths/src/library-code.cpp new file mode 100644 index 0000000..7e49a69 --- /dev/null +++ b/tests/relative-paths/src/library-code.cpp @@ -0,0 +1,6 @@ +// Created by Anthony Printup on 9/18/2023. +#include + +extern "C" void library_function() { + std::puts("Hello from library_function!"); +} diff --git a/tests/relative-paths/src/main.cpp b/tests/relative-paths/src/main.cpp new file mode 100644 index 0000000..3bef1f9 --- /dev/null +++ b/tests/relative-paths/src/main.cpp @@ -0,0 +1,12 @@ +// Created by Anthony Printup on 9/18/2023. +#include + +#ifdef WIN32 +extern "C" void library_function(); +#endif +int main() { + puts("Hello from cmkr(relative-paths)!"); +#ifdef WIN32 + library_function(); +#endif +}