Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

Allow multiple cpp files in apps and libs directories. #41

Merged
merged 9 commits into from
Apr 25, 2023
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
[submodule "external/cturtle"]
path = external/cturtle
url = https://github.com/dimas1185/cturtle
[submodule "external/Mustache"]
path = external/Mustache
url = https://github.com/kainjow/Mustache
[submodule "external/fmt"]
path = external/fmt
url = https://github.com/fmtlib/fmt
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ ignored-modules=
# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
# complex, nested conditions.
limit-inference-results=100
limit-inference-results=140

# List of plugins (as comma separated values of python module names) to load,
# usually to register additional checkers.
Expand Down
2 changes: 0 additions & 2 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,3 @@ add_subdirectory(fmt)
set(CTURTLE_ENABLE_TESTS OFF CACHE INTERNAL "Skip cturtle tests")
set(CTURTLE_ENABLE_INSTALL OFF CACHE INTERNAL "Skip cturtle install")
add_subdirectory(cturtle)

add_subdirectory(Mustache)
1 change: 0 additions & 1 deletion external/Mustache
Submodule Mustache deleted from 04277d
123 changes: 52 additions & 71 deletions include/antler/project/cmake.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@
#include <stdexcept>
#include <string_view>

#include <mustache.hpp>


namespace antler::project {

namespace km = kainjow::mustache;

/// @brief struct to encapsulate a CMakeLists.txt file
struct cmake_lists {
constexpr inline static std::string_view filename = "CMakeLists.txt";
Expand Down Expand Up @@ -54,8 +50,8 @@ namespace antler::project {
/// @param v object that will be inserted in this CMakeLists.txt
/// @return CMakeLists stream
template<typename T>
inline std::ostream& operator<<(T&& v) {
outs << std::forward<T>(v);
inline std::ostream& operator<<(T&& v) {
outs << std::forward<T>(v);
outs.flush();
return outs;
}
Expand All @@ -76,17 +72,17 @@ namespace antler::project {
constexpr inline static std::string_view libs_dir_name = "libs";
constexpr inline static std::string_view tests_dir_name = "tests";

// `mustache` templates for the cmake
static km::mustache add_subdirectory_template;
static km::mustache add_subdirectory2_template;
static km::mustache preamble_template;
static km::mustache project_stub_template;
static km::mustache target_compile_template;
static km::mustache target_include_template;
static km::mustache target_link_libs_template;
static km::mustache entry_template;
static km::mustache add_contract_template;
static km::mustache add_library_template;
// std::format templates for the cmake
static std::string_view add_subdirectory_template;
static std::string_view add_subdirectory2_template;
static std::string_view preamble_template;
static std::string_view project_stub_template;
static std::string_view target_compile_template;
static std::string_view target_include_template;
static std::string_view target_link_libs_template;
static std::string_view entry_template;
static std::string_view add_contract_template;
static std::string_view add_library_template;

cmake(const project& proj)
: proj(&proj),
Expand Down Expand Up @@ -117,23 +113,26 @@ namespace antler::project {
}

template <typename Stream>
inline void emit_add_subdirectory(Stream& s, system::fs::path path, std::string_view name) noexcept {
s << add_subdirectory_template.render(datum{"path", (path / name).string()});
inline void emit_add_subdirectory(Stream& s, system::fs::path path, std::string_view name) noexcept {
s << fmt::format(add_subdirectory_template, (path / name).string());
}

template <typename Stream>
inline void emit_preamble(Stream& s) noexcept {
s << preamble_template.render(datum{"tool", "antler-proj"}
("major", minimum_major)
("minor", minimum_minor)
("proj_name", proj->name())
("proj_major", proj->version().major())
("proj_minor", proj->version().minor())
("proj_patch", proj->version().patch()));
s << fmt::format(preamble_template,
"antler-proj",
minimum_major,
minimum_minor,
proj->name(),
proj->version().major(),
proj->version().minor(),
proj->version().patch());
}

template <typename Stream>
inline void emit_project_stub(Stream& s) noexcept { s << project_stub_template.render({}); }
inline void emit_project_stub(Stream& s) noexcept {
s << fmt::format(project_stub_template);
}

template <typename Populators, typename Stream, typename Tag>
inline void emit_dependencies(Populators&& pops, Stream& s, const object<Tag>& obj) noexcept {
Expand All @@ -142,42 +141,49 @@ namespace antler::project {
system::debug_log("emitting dependencies for {0} at {1}", dep.name(), dep.location().empty() ? "local" : dep.location());
if (!dep.location().empty()) {
std::string repo = std::string(github::get_repo(dep.location()));
s << add_subdirectory2_template.render(datum{"src_path", "../../dependencies/"+repo+"/build/apps/"}
("bin_path", repo));
s << target_link_libs_template.render(datum{"target_name", target_name(obj)}
("dep_name", pops.get_mapping(dep)+"-"+dep.name()));
s << fmt::format(add_subdirectory2_template,
"../../dependencies/"+repo+"/build/apps/",
repo);
s << fmt::format(target_link_libs_template,
target_name(obj),
pops.get_mapping(dep)+"-"+dep.name());
} else {
s << target_link_libs_template.render(datum{"target_name", target_name(obj)}
("dep_name", target_name(dep)));
s << fmt::format(target_link_libs_template,
target_name(obj),
target_name(dep));
}
}
s << "\n";
}

template <typename Stream>
inline void emit_entry(Stream& s) noexcept { s << entry_template.render(datum{"proj", proj->name()}); }
inline void emit_entry(Stream& s) noexcept { s << fmt::format(entry_template, proj->name()); }

template <typename Pops, typename Stream, typename Tag>
inline void emit_object(Pops& pops, Stream& s, const object<Tag>& obj) {
km::mustache& temp = std::is_same_v<Tag, app_tag> ? add_contract_template : add_library_template;
std::string_view temp = std::is_same_v<Tag, app_tag> ? add_contract_template : add_library_template;

s << fmt::format(temp,
obj.name(),
target_name(obj),
system::extension(obj.language()));

s << temp.render(datum{"obj_name", obj.name()}
("target_name", target_name(obj))
("obj_source", std::string(obj.name())+system::extension(obj.language())));

s << target_include_template.render(datum{"target_name", target_name(obj)}
("obj_name", obj.name()));
s << fmt::format(target_include_template,
target_name(obj),
obj.name());

for (const auto& o : obj.compile_options()) {
s << target_compile_template.render(datum{"target_name", target_name(obj)}
("opt", o));
s << fmt::format(target_compile_template,
target_name(obj),
o);
}

s << "\n";

for (const auto& o : obj.link_options()) {
s << target_link_libs_template.render(datum{"target_name", target_name(obj)}
("dep_name", o));
s << fmt::format(target_link_libs_template,
target_name(obj),
o);
}

s << "\n";
Expand Down Expand Up @@ -220,31 +226,6 @@ namespace antler::project {
}

private:

// simple helper to clean km::data usage
struct datum {
template <typename T>
decltype(auto) fwrd(T&& val) {
std::stringstream ss;
ss << std::forward<T>(val);
return ss.str();
}

template <typename Str, typename T>
inline datum(Str&& key, T&& val)
: data(std::forward<Str>(key), fwrd(std::forward<T>(val))) {}

template <typename Str, typename T>
datum& operator()(Str&& key, T&& val) {
data.set(std::forward<Str>(key), fwrd(std::forward<T>(val)));
return *this;
}

operator km::data() const { return data; }
operator km::data&() { return data; }

km::data data;
};

const project* proj = nullptr; // non-owning pointer to project
system::fs::path base_path;
Expand Down
42 changes: 0 additions & 42 deletions include/antler/project/mustache.hpp

This file was deleted.

14 changes: 6 additions & 8 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,20 @@ pkg_check_modules(CURL libcurl REQUIRED)

add_library(antler-project
cmake_templates.cpp
dependency.cpp
location.cpp
dependency.cpp
location.cpp
populator.cpp
project.cpp
version_constraint.cpp
version_constraint.cpp
)

target_include_directories(antler-project PUBLIC ../include
target_include_directories(antler-project PUBLIC ../include
${CMAKE_CURRENT_BINARY_DIR}/../include
${CMAKE_SOURCE_DIR}/external/Mustache
${CURL_INCLUDE_DIRS}
)
target_link_libraries(antler-project PUBLIC mustache
nlohmann_json::nlohmann_json
target_link_libraries(antler-project PUBLIC nlohmann_json::nlohmann_json
yaml-cpp::yaml-cpp
bluegrass::cturtle
${CURL_LIBRARIES}
-lstdc++fs)
set_property(TARGET antler-project PROPERTY CXX_STANDARD 17)
set_property(TARGET antler-project PROPERTY CXX_STANDARD 17)
94 changes: 54 additions & 40 deletions src/cmake_templates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,58 @@

namespace antler::project {

km::mustache cmake::add_subdirectory_template = {"add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/{{path}})\n\n"};
km::mustache cmake::add_subdirectory2_template = {"add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/{{src_path}} ${CMAKE_CURRENT_BINARY_DIR}/{{bin_path}})\n\n"};

km::mustache cmake::preamble_template = {"# Generated with {{tool}}, modify at your own risk\n"
"cmake_minimum_required(VERSION {{major}}.{{minor}})\n"
"project(\"{{proj_name}}\" VERSION {{proj_major}}.{{proj_minor}}.{{proj_patch}})\n\n"};

km::mustache cmake::project_stub_template = {"find_package(cdt)\n\n"
"add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libs ${CMAKE_CURRENT_BINARY_DIR}/libs)\n"
"add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../tests ${CMAKE_CURRENT_BINARY_DIR}/tests)\n\n"};

km::mustache cmake::target_compile_template = {"target_compile_options({{target_name}} PUBLIC {{opt}})\n\n"};

km::mustache cmake::target_include_template = {"target_include_directories({{target_name}}"
" PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../include"
" ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/{{obj_name}}"
" ./)\n\n"};

km::mustache cmake::target_link_libs_template = {"target_link_libraries({{target_name}} PUBLIC {{dep_name}})\n\n"};

km::mustache cmake::entry_template = {"include(ExternalProject)\n"
"if(CDT_ROOT STREQUAL \"\" OR NOT CDT_ROOT)\n"
" find_package(cdt)\n"
"endif()\n\n"
"ExternalProject_Add(\n"
" {{proj}}_project\n"
" SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/apps\n"
" BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/{{proj}}\n"
" CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CDT_ROOT}/lib/cmake/cdt/CDTWasmToolchain.cmake\n"
" UPDATE_COMMAND \"\"\n"
" PATCH_COMMAND \"\"\n"
" TEST_COMMAND \"\"\n"
" INSTALL_COMMAND \"\"\n"
" BUILD_ALWAYS 1\n"
")\n\n"};

km::mustache cmake::add_contract_template = {"add_contract({{obj_name}} {{target_name}} ${CMAKE_CURRENT_SOURCE_DIR}/../../../apps/{{obj_name}}/{{obj_source}})\n\n"};
km::mustache cmake::add_library_template = {"add_library({{target_name}} ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/{{obj_name}}/{{obj_source}})\n\n"};

// 0: path
std::string_view cmake::add_subdirectory_template = {"add_subdirectory(${{CMAKE_CURRENT_SOURCE_DIR}}/{0})\n\n"};
// 0: src_path, 1: bin_path
std::string_view cmake::add_subdirectory2_template = {"add_subdirectory(${{CMAKE_CURRENT_SOURCE_DIR}}/{0}\n"
" ${{CMAKE_CURRENT_BINARY_DIR}}/{1})\n\n"};

// 0: tool, 1: major, 2: minor, 3: proj_name, 4: proj_major, 5: proj_minor, 6: proj_patch
std::string_view cmake::preamble_template = {"# Generated with {0}, modify at your own risk\n"
"cmake_minimum_required(VERSION {1}.{2})\n"
"project(\"{3}\" VERSION {4}.{5}.{6})\n\n"};

// NONE, but we still need to send it through format.
std::string_view cmake::project_stub_template = {"find_package(cdt)\n\n"
"add_subdirectory(${{CMAKE_CURRENT_SOURCE_DIR}}/../libs ${{CMAKE_CURRENT_BINARY_DIR}}/libs)\n"
"add_subdirectory(${{CMAKE_CURRENT_SOURCE_DIR}}/../tests ${{CMAKE_CURRENT_BINARY_DIR}}/tests)\n\n"};

// 0: target_name, 1: opt
std::string_view cmake::target_compile_template = {"target_compile_options({0} PUBLIC {1})\n\n"};

// 0: target name, 1: obj name
std::string_view cmake::target_include_template = {"target_include_directories({0}\n"
" PUBLIC ${{CMAKE_CURRENT_SOURCE_DIR}}/../../../include\n"
" ${{CMAKE_CURRENT_SOURCE_DIR}}/../../../include/{1}\n"
" ./)\n\n"};

// 0: target name, 1: link libs
std::string_view cmake::target_link_libs_template = {"target_link_libraries({0} PUBLIC {1})\n\n"};

//0: proj
std::string_view cmake::entry_template = {"include(ExternalProject)\n"
"if(CDT_ROOT STREQUAL \"\" OR NOT CDT_ROOT)\n"
" find_package(cdt)\n"
"endif()\n\n"
"ExternalProject_Add(\n"
" {0}_project\n"
" SOURCE_DIR ${{CMAKE_CURRENT_SOURCE_DIR}}/apps\n"
" BINARY_DIR ${{CMAKE_CURRENT_BINARY_DIR}}/{0}\n"
" CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${{CDT_ROOT}}/lib/cmake/cdt/CDTWasmToolchain.cmake\n"
" UPDATE_COMMAND \"\"\n"
" PATCH_COMMAND \"\"\n"
" TEST_COMMAND \"\"\n"
" INSTALL_COMMAND \"\"\n"
" BUILD_ALWAYS 1\n"
")\n\n"};

// 0: object name, 1: target name, 2: source extension
std::string_view cmake::add_contract_template = {"file(GLOB {1}-source ${{CMAKE_CURRENT_SOURCE_DIR}}/../../../apps/{0}/*{2})\n"
"add_contract({0} {1} ${{{1}-source}})\n\n"};

// 0: object name, 1: target name, 2: source extension
std::string_view cmake::add_library_template = {"file(GLOB {1}-source ${{CMAKE_CURRENT_SOURCE_DIR}}/../../../libs/{0}/*{2})\n\n"
"add_library({0} ${{{1}-source}})\n\n"};


} // namespace antler::project

Loading