Merge pull request #20 from build-cpp/conditional-subdirs

Add support for conditional subdirs
vcpkg-wip
Duncan Ogilvie 4 years ago committed by GitHub
commit 7cf16eaf70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

13
CMakeLists.txt generated

@ -53,8 +53,10 @@ add_subdirectory(tests)
set(CMAKE_FOLDER ${CMKR_CMAKE_FOLDER}) set(CMAKE_FOLDER ${CMKR_CMAKE_FOLDER})
# Target cmkr # Target cmkr
unset(cmkr_SOURCES) set(CMKR_TARGET cmkr)
set(cmkr_SOURCES "")
list(APPEND cmkr_SOURCES list(APPEND cmkr_SOURCES
"src/args.cpp" "src/args.cpp"
@ -79,7 +81,12 @@ list(APPEND cmkr_SOURCES
cmake.toml cmake.toml
) )
add_executable(cmkr ${cmkr_SOURCES}) set(CMKR_SOURCES ${cmkr_SOURCES})
add_executable(cmkr)
if(cmkr_SOURCES)
target_sources(cmkr PRIVATE ${cmkr_SOURCES})
endif()
get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT) get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
if(NOT CMKR_VS_STARTUP_PROJECT) if(NOT CMKR_VS_STARTUP_PROJECT)
@ -103,6 +110,8 @@ target_link_libraries(cmkr PRIVATE
ordered_map ordered_map
) )
unset(CMKR_TARGET)
unset(CMKR_SOURCES)
install( install(
TARGETS TARGETS
cmkr cmkr

@ -98,7 +98,7 @@ struct CMake {
std::string build_dir = "build"; std::string build_dir = "build";
std::string generator; std::string generator;
std::string config; std::string config;
std::vector<std::string> subdirs; Condition<std::vector<std::string>> subdirs;
std::vector<std::string> cppflags; std::vector<std::string> cppflags;
std::vector<std::string> cflags; std::vector<std::string> cflags;
std::vector<std::string> linkflags; std::vector<std::string> linkflags;

@ -390,7 +390,9 @@ struct Generator {
cmd("if")(RawArg(cmake.conditions[condition])); cmd("if")(RawArg(cmake.conditions[condition]));
} }
fn(condition, itr.second); if (!itr.second.empty()) {
fn(condition, itr.second);
}
if (!condition.empty()) { if (!condition.empty()) {
cmd("endif")(); cmd("endif")();
@ -573,25 +575,30 @@ int generate_cmake(const char *path, bool root) {
// generate_cmake is called on the subdirectories recursively later // generate_cmake is called on the subdirectories recursively later
if (!cmake.subdirs.empty()) { if (!cmake.subdirs.empty()) {
for (const auto &dir : cmake.subdirs) { gen.handle_condition(cmake.subdirs, [&](const std::string &, const std::vector<std::string> &subdirs) {
// clang-format off for (const auto &dir : subdirs) {
comment(dir); // clang-format off
cmd("set")("CMKR_CMAKE_FOLDER", "${CMAKE_FOLDER}"); comment(dir);
cmd("if")("CMAKE_FOLDER"); cmd("set")("CMKR_CMAKE_FOLDER", "${CMAKE_FOLDER}");
cmd("set")("CMAKE_FOLDER", "${CMAKE_FOLDER}/" + dir); cmd("if")("CMAKE_FOLDER");
cmd("else")(); cmd("set")("CMAKE_FOLDER", "${CMAKE_FOLDER}/" + dir);
cmd("set")("CMAKE_FOLDER", dir); cmd("else")();
cmd("endif")(); cmd("set")("CMAKE_FOLDER", dir);
// clang-format on cmd("endif")();
cmd("add_subdirectory")(dir); // clang-format on
cmd("set")("CMAKE_FOLDER", "${CMKR_CMAKE_FOLDER}").endl();
} cmd("add_subdirectory")(dir);
cmd("set")("CMAKE_FOLDER", "${CMKR_CMAKE_FOLDER}").endl();
}
});
endl(); endl();
} }
if (!cmake.targets.empty()) { if (!cmake.targets.empty()) {
for (const auto &target : cmake.targets) { for (const auto &target : cmake.targets) {
comment("Target " + target.name); comment("Target " + target.name);
cmd("set")("CMKR_TARGET", target.name);
gen.handle_condition(target.include_before, gen.handle_condition(target.include_before,
[&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); }); [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); });
gen.handle_condition(target.cmake_before, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); }); gen.handle_condition(target.cmake_before, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); });
@ -599,7 +606,7 @@ int generate_cmake(const char *path, bool root) {
auto sources_var = target.name + "_SOURCES"; auto sources_var = target.name + "_SOURCES";
bool added_toml = false; bool added_toml = false;
cmd("unset")(sources_var).endl(); cmd("set")(sources_var, RawArg("\"\"")).endl();
gen.handle_condition(target.sources, [&](const std::string &condition, const std::vector<std::string> &condition_sources) { gen.handle_condition(target.sources, [&](const std::string &condition, const std::vector<std::string> &condition_sources) {
auto sources = expand_cmake_paths(condition_sources, path); auto sources = expand_cmake_paths(condition_sources, path);
if (sources.empty()) { if (sources.empty()) {
@ -616,6 +623,7 @@ int generate_cmake(const char *path, bool root) {
if (!added_toml && target.type != cmake::target_interface) { if (!added_toml && target.type != cmake::target_interface) {
cmd("list")("APPEND", sources_var, std::vector<std::string>{"cmake.toml"}).endl(); cmd("list")("APPEND", sources_var, std::vector<std::string>{"cmake.toml"}).endl();
} }
cmd("set")("CMKR_SOURCES", "${" + sources_var + "}");
std::string add_command; std::string add_command;
std::string target_type; std::string target_type;
@ -656,7 +664,13 @@ int generate_cmake(const char *path, bool root) {
assert("Unimplemented enum value" && false); assert("Unimplemented enum value" && false);
} }
cmd(add_command)(target.name, target_type, "${" + target.name + "_SOURCES}").endl(); cmd(add_command)(target.name, target_type).endl();
// clang-format off
cmd("if")(sources_var);
cmd("target_sources")(target.name, target.type == cmake::target_interface ? "INTERFACE" : "PRIVATE", "${" + sources_var + "}");
cmd("endif")().endl();
// clang-format on
// The first executable target will become the Visual Studio startup project // The first executable target will become the Visual Studio startup project
if (target.type == cmake::target_executable) { if (target.type == cmake::target_executable) {
@ -696,6 +710,9 @@ int generate_cmake(const char *path, bool root) {
gen.handle_condition(target.include_after, gen.handle_condition(target.include_after,
[&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); }); [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); });
gen.handle_condition(target.cmake_after, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); }); gen.handle_condition(target.cmake_after, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); });
cmd("unset")("CMKR_TARGET");
cmd("unset")("CMKR_SOURCES");
} }
} }
@ -755,10 +772,12 @@ int generate_cmake(const char *path, bool root) {
} }
} }
for (const auto &sub : cmake.subdirs) { for (const auto &itr : cmake.subdirs) {
auto subpath = fs::path(path) / fs::path(sub); for (const auto &sub : itr.second) {
if (fs::exists(subpath / "cmake.toml")) auto subpath = fs::path(path) / fs::path(sub);
generate_cmake(subpath.string().c_str(), false); if (fs::exists(subpath / "cmake.toml"))
generate_cmake(subpath.string().c_str(), false);
}
} }
return 0; return 0;

10
tests/CMakeLists.txt generated

@ -28,3 +28,13 @@ add_test(
build build
) )
add_test(
NAME
interface
WORKING_DIRECTORY
"${CMAKE_CURRENT_LIST_DIR}/interface"
COMMAND
$<TARGET_FILE:cmkr>
build
)

@ -9,3 +9,9 @@ name = "conditions"
command = "$<TARGET_FILE:cmkr>" command = "$<TARGET_FILE:cmkr>"
working-directory = "${CMAKE_CURRENT_LIST_DIR}/conditions" working-directory = "${CMAKE_CURRENT_LIST_DIR}/conditions"
arguments = ["build"] arguments = ["build"]
[[test]]
name = "interface"
command = "$<TARGET_FILE:cmkr>"
working-directory = "${CMAKE_CURRENT_LIST_DIR}/interface"
arguments = ["build"]

@ -0,0 +1,11 @@
[project]
name = "interface"
[target.mylib]
type = "interface"
include-directories = ["include"]
[target.example]
type = "executable"
sources = ["src/main.cpp"]
link-libraries = ["mylib"]

@ -0,0 +1,4 @@
namespace mylib
{
static const char* version() { return "v1.0"; }
} // namespace mylib

@ -0,0 +1,8 @@
#include <cstdio>
#include "mylib/mylib.hpp"
int main()
{
printf("mylib version: %s\n", mylib::version())
}
Loading…
Cancel
Save