init
This commit is contained in:
commit
45c2bf9426
25 changed files with 1692 additions and 0 deletions
10
src/file.cc
Normal file
10
src/file.cc
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "grbc/spec.h"
|
||||
#include <filesystem>
|
||||
|
||||
std::string grbc_file(const std::string &file_path) {
|
||||
if (!std::filesystem::exists(file_path)) {
|
||||
grbc_exception("grbc_file gave path '" + file_path + "', which does not exist!");
|
||||
}
|
||||
|
||||
return file_path;
|
||||
}
|
22
src/generator.cc
Normal file
22
src/generator.cc
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "grbc/generator.h"
|
||||
#include "grbc/helpers.h"
|
||||
#include "grbc/spec.h"
|
||||
#include "grbc/state.h"
|
||||
#include <fstream>
|
||||
|
||||
void grbc_build(const std::string &generator_id) {
|
||||
log_msg(("finding generator with name: " + generator_id).c_str());
|
||||
|
||||
for (auto &gen : GState::get().generators) {
|
||||
if (gen.name == generator_id) {
|
||||
GeneratorResult result = gen.func();
|
||||
|
||||
std::ofstream ofs(result.file_name);
|
||||
ofs << result.content;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
grbc_exception("Could not find valid generator!");
|
||||
}
|
93
src/main.cc
Normal file
93
src/main.cc
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include "grbc/state.h"
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
|
||||
#include "grbc/helpers.h"
|
||||
#include "grbc/spec.h"
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
int main() {
|
||||
log_msg("opening lua libraries...");
|
||||
|
||||
auto &lua = GState::get().lua;
|
||||
|
||||
lua.open_libraries(sol::lib::base, sol::lib::coroutine, sol::lib::string,
|
||||
sol::lib::io, sol::lib::package, sol::lib::math);
|
||||
|
||||
log_msg("setting up runtime...");
|
||||
|
||||
// TargetInfo
|
||||
lua.new_usertype<TargetInfo>("TargetInfo", "name", &TargetInfo::name);
|
||||
|
||||
// PackageConfig
|
||||
lua.new_usertype<PackageConfig>(
|
||||
"PackageConfig", "name", &PackageConfig::name, "libraries",
|
||||
&PackageConfig::libraries, "include_dirs", &PackageConfig::include_dirs,
|
||||
"compile_flags", &PackageConfig::compile_flags, "linker_flags",
|
||||
&PackageConfig::linker_flags);
|
||||
|
||||
// GlobalConfig
|
||||
lua.new_usertype<GlobalConfig>(
|
||||
"GlobalConfig", "engine_version", &GlobalConfig::engine_version,
|
||||
"architecture", &GlobalConfig::architecture, "target",
|
||||
&GlobalConfig::target, "target_config", &GlobalConfig::target_config);
|
||||
|
||||
// Platform
|
||||
lua.new_usertype<Platform>("Platform", "name", &Platform::name,
|
||||
"cxx_compiler", &Platform::cxx_compiler,
|
||||
"cc_compiler", &Platform::cc_compiler,
|
||||
"platform_type", &Platform::platform_type, "is_64bit", &Platform::is_64bit);
|
||||
|
||||
// PlatformType
|
||||
lua.new_enum<PlatformType>("PlatformType", {{"Win32", PlatformType_Win32},
|
||||
{"Linux", PlatformType_Linux}});
|
||||
|
||||
// LanguageType
|
||||
lua.new_enum<LanguageType>("LanguageType", {
|
||||
{ "Cpp", LanguageType_CPP },
|
||||
{ "C", LanguageType_C }
|
||||
});
|
||||
|
||||
// ExecutableConfig
|
||||
lua.new_usertype<ExecutableConfig>(
|
||||
"ExecutableConfig", sol::constructors<ExecutableConfig(sol::table)>(),
|
||||
"name", &ExecutableConfig::name, "files", &ExecutableConfig::files,
|
||||
"requirments", &ExecutableConfig::requirements, "compile_flags",
|
||||
&ExecutableConfig::compile_flags, "linker_flags",
|
||||
&ExecutableConfig::linker_flags, "include_dirs",
|
||||
&ExecutableConfig::include_dirs, "language_type", &ExecutableConfig::language_type);
|
||||
|
||||
// Package
|
||||
lua.new_usertype<Package>("Package", sol::constructors<Package(sol::table)>(), "name", &Package::name, "compiler_flags",
|
||||
&Package::compiler_flags, "linker_flags",
|
||||
&Package::linker_flags);
|
||||
|
||||
lua.set("grbc_want_version", grbc_want_version);
|
||||
lua.set("grbc_exception", grbc_exception);
|
||||
lua.set("grbc_get_config", grbc_get_config);
|
||||
lua.set("grbc_file", grbc_file);
|
||||
lua.set("grbc_executable", grbc_executable);
|
||||
lua.set("grbc_load_platform", grbc_load_platform);
|
||||
lua.set("grbc_set_platform", grbc_set_platform);
|
||||
lua.set("grbc_find_compiler", grbc_find_compiler);
|
||||
lua.set("grbc_build", grbc_build);
|
||||
lua.set("grbc_replace_string", grbc_replace_string);
|
||||
lua.set("grbc_object_file", grbc_object_file);
|
||||
lua.set("grbc_include_dirs_to_clflags", grbc_include_dirs_to_cflags);
|
||||
lua.set("grbc_log", grbc_log);
|
||||
lua.set("grbc_is_32bit", grbc_is_32bit);
|
||||
lua.set("grbc_is_64bit", grbc_is_64bit);
|
||||
lua.set("grbc_is_linux", grbc_is_linux);
|
||||
lua.set("grbc_is_win32", grbc_is_win32);
|
||||
lua.set("grbc_get_platform", grbc_get_platform);
|
||||
|
||||
// Load generators
|
||||
|
||||
GState::get().generators.push_back({
|
||||
.name = "ninja",
|
||||
.func = ninja_generator
|
||||
});
|
||||
|
||||
log_msg("loading HConfig...");
|
||||
|
||||
lua.script_file("HConfig");
|
||||
}
|
128
src/ninja.cc
Normal file
128
src/ninja.cc
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include "grbc/ninja.h"
|
||||
#include "grbc/generator.h"
|
||||
#include "grbc/helpers.h"
|
||||
#include "grbc/spec.h"
|
||||
#include "grbc/state.h"
|
||||
|
||||
std::string ninja_build_rule_compile_cxx() {
|
||||
std::string compiler_path = GState::get().current_platform.cxx_compiler;
|
||||
|
||||
std::string result =
|
||||
"## build_rule_compile_cxx ##\n\ncxx_path = " + compiler_path + "\n";
|
||||
result += "rule cxx\n";
|
||||
result += " command = $cxx_path -MMD -MT $out -MF $out.d $p_cflags -c $in "
|
||||
"-o $out\n";
|
||||
result += " description = Compiling C++ object $in\n";
|
||||
result += " depfile = $out.d\n";
|
||||
result += " deps = gcc\n";
|
||||
result += "\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ninja_build_rule_compile_cc() {
|
||||
std::string compiler_path = GState::get().current_platform.cc_compiler;
|
||||
|
||||
std::string result =
|
||||
"## build_rule_compile_cc ##\n\ncc_path = " + compiler_path + "\n";
|
||||
result += "rule cc\n";
|
||||
result += " command = $cc_path -MMD -MT $out -MF $out.d $p_cflags -c $in "
|
||||
"-o $out\n";
|
||||
result += " description = Compiling C object $in\n";
|
||||
result += " depfile = $out.d\n";
|
||||
result += " deps = gcc\n";
|
||||
result += "\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ninja_build_rule_link_cxx() {
|
||||
std::string result = "## build_rule_link_cxx ##\n\n";
|
||||
result += "rule link_cxx\n";
|
||||
result += " command = $cxx_path $p_cflags -o $out $in $p_linker_flags\n";
|
||||
result += " description = Linking C++ executables $out\n\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ninja_build_rule_link_cc() {
|
||||
std::string result = "## build_rule_link_cc ##\n\n";
|
||||
result += "rule link_cc\n";
|
||||
result += " command = $cc_path $p_cflags -o $out $in $p_linker_flags\n";
|
||||
result += " description = Linking C executables $out\n\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string
|
||||
ninja_build_rule_compile_file(const GeneratorCompileCommand &compile_cmd) {
|
||||
std::string result = "## Compile: " + compile_cmd.source_file + " ##\n\n";
|
||||
|
||||
std::string compiler_rule = "cxx";
|
||||
|
||||
if (compile_cmd.language_type == LanguageType_C)
|
||||
compiler_rule = "cc";
|
||||
|
||||
result += "build $builddir/" + compile_cmd.object_file + ": " +
|
||||
compiler_rule + " " + compile_cmd.source_file + "\n";
|
||||
result += " p_cflags = " + compile_cmd.compiler_flags + "\n\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ninja_build_default_variables() {
|
||||
std::string result = "## Default variables ##\n\n";
|
||||
result += "builddir = " + grbc_get_config().build_dir + "\n";
|
||||
|
||||
result += "\n"; // keep as the last line
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ninja_build_rule_link_exe_target(
|
||||
const GeneratorLinkExecutableCommand &link_cmd) {
|
||||
std::string result = "## Link: " + link_cmd.output_exe + " ##\n\n";
|
||||
|
||||
std::string file_list;
|
||||
|
||||
for (auto &file : link_cmd.object_files) {
|
||||
file_list += "$builddir/" + file + " ";
|
||||
}
|
||||
|
||||
file_list.pop_back();
|
||||
|
||||
result += "build " + link_cmd.output_exe + ": link_cxx " + file_list + "\n";
|
||||
result += " p_linker_flags = " + link_cmd.linker_flags + "\n";
|
||||
result += " p_cflags = \n\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Ninja generator entry
|
||||
|
||||
GeneratorResult ninja_generator() {
|
||||
GeneratorResult result{};
|
||||
|
||||
log_msg("running ninja final generation...");
|
||||
|
||||
result.file_name = "build.ninja";
|
||||
|
||||
result.content += "### GRBC BUILT-IN NINJA GENERATOR ###\n\n";
|
||||
result.content += ninja_build_default_variables();
|
||||
result.content += ninja_build_rule_compile_cc();
|
||||
result.content += ninja_build_rule_compile_cxx();
|
||||
result.content += ninja_build_rule_link_cc();
|
||||
result.content += ninja_build_rule_link_cxx();
|
||||
|
||||
for (auto &target : GState::get().targets) {
|
||||
for (auto &compile_cmd : target.compile_commands) {
|
||||
result.content += ninja_build_rule_compile_file(compile_cmd);
|
||||
}
|
||||
|
||||
for (auto &link_cmd : target.link_executable_commands) {
|
||||
result.content += ninja_build_rule_link_exe_target(link_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
89
src/platform.cc
Normal file
89
src/platform.cc
Normal file
|
@ -0,0 +1,89 @@
|
|||
#include "grbc/helpers.h"
|
||||
#include "grbc/spec.h"
|
||||
#include "grbc/state.h"
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
|
||||
void grbc_set_platform(const Platform &platform) {
|
||||
GState::get().current_platform = platform;
|
||||
|
||||
if (!std::filesystem::exists(platform.cxx_compiler)) {
|
||||
grbc_exception("C++ compiler path does not exist at '" +
|
||||
platform.cxx_compiler + "'");
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(platform.cc_compiler)) {
|
||||
grbc_exception("C compiler path does not exist at '" +
|
||||
platform.cc_compiler + "'");
|
||||
}
|
||||
|
||||
log_msg("--- Platform config: ---");
|
||||
|
||||
log_msg(("C++ compiler = " + platform.cxx_compiler).c_str());
|
||||
log_msg(("C compiler = " + platform.cc_compiler).c_str());
|
||||
}
|
||||
|
||||
void grbc_load_platform(const std::string &file_path) {
|
||||
Platform platform = GState::get().lua.script_file(file_path);
|
||||
|
||||
grbc_set_platform(platform);
|
||||
}
|
||||
|
||||
std::string grbc_find_compiler(const std::string &compiler_name) {
|
||||
#if defined(WIN32)
|
||||
std::string path_var = std::getenv("Path");
|
||||
|
||||
std::vector<std::string> paths = split_string(path_var, ";");
|
||||
|
||||
for (auto ¤t_path : paths) {
|
||||
if (std::filesystem::exists(
|
||||
std::filesystem::path(current_path) /
|
||||
std::filesystem::path(compiler_name + ".exe"))) {
|
||||
return std::filesystem::path(current_path) /
|
||||
std::filesystem::path(compiler_name + ".exe");
|
||||
}
|
||||
}
|
||||
|
||||
grbc_exception("Failed to locate compiler with name '" + compiler_name + "'");
|
||||
|
||||
#elif defined(__linux__)
|
||||
std::string path_var = std::getenv("PATH");
|
||||
|
||||
std::vector<std::string> paths = split_string(path_var, ":");
|
||||
|
||||
for (auto ¤t_path : paths) {
|
||||
if (std::filesystem::exists(std::filesystem::path(current_path) /
|
||||
std::filesystem::path(compiler_name))) {
|
||||
return std::filesystem::path(current_path) /
|
||||
std::filesystem::path(compiler_name);
|
||||
}
|
||||
}
|
||||
|
||||
grbc_exception("Failed to locate compiler with name '" + compiler_name + "'");
|
||||
|
||||
#else
|
||||
#error Invalid platform for grbc_find_compiler
|
||||
#endif
|
||||
|
||||
return "NoPlatform";
|
||||
}
|
||||
|
||||
bool grbc_is_win32() {
|
||||
return grbc_get_platform() == PlatformType_Win32;
|
||||
}
|
||||
|
||||
bool grbc_is_linux() {
|
||||
return grbc_get_platform() == PlatformType_Linux;
|
||||
}
|
||||
|
||||
PlatformType grbc_get_platform() {
|
||||
return GState::get().current_platform.platform_type;
|
||||
}
|
||||
|
||||
bool grbc_is_64bit() {
|
||||
return GState::get().current_platform.is_64bit;
|
||||
}
|
||||
|
||||
bool grbc_is_32bit() {
|
||||
return !grbc_is_64bit();
|
||||
}
|
57
src/target_exe.cc
Normal file
57
src/target_exe.cc
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "grbc/generator.h"
|
||||
#include "grbc/spec.h"
|
||||
#include "grbc/state.h"
|
||||
|
||||
TargetInfo grbc_executable(const ExecutableConfig &executable_config) {
|
||||
TargetInfo target_config{};
|
||||
|
||||
std::string exe_name = executable_config.name;
|
||||
std::string compiler_args;
|
||||
std::string linker_args;
|
||||
|
||||
for (auto &package : executable_config.requirements) {
|
||||
compiler_args += package.compiler_flags + " ";
|
||||
linker_args += package.linker_flags + " ";
|
||||
}
|
||||
|
||||
for (auto &linker_arg : executable_config.linker_flags) {
|
||||
linker_args += linker_arg + " ";
|
||||
}
|
||||
|
||||
for (auto &compiler_arg : executable_config.compile_flags) {
|
||||
compiler_args += compiler_arg + " ";
|
||||
}
|
||||
|
||||
// Include directories
|
||||
|
||||
compiler_args += grbc_include_dirs_to_cflags(executable_config.include_dirs);
|
||||
|
||||
GeneratorTarget target{};
|
||||
|
||||
std::vector<std::string> object_files;
|
||||
|
||||
for (auto &src_file : executable_config.files) {
|
||||
GeneratorCompileCommand compile_cmd{};
|
||||
compile_cmd.source_file = src_file;
|
||||
compile_cmd.object_file = grbc_object_file(src_file);
|
||||
compile_cmd.compiler_flags = compiler_args;
|
||||
compile_cmd.language_type = executable_config.language_type;
|
||||
|
||||
object_files.push_back(compile_cmd.object_file);
|
||||
|
||||
target.compile_commands.push_back(compile_cmd);
|
||||
}
|
||||
|
||||
// Final executable link
|
||||
|
||||
GeneratorLinkExecutableCommand executable_link_cmd{};
|
||||
executable_link_cmd.linker_flags = linker_args;
|
||||
executable_link_cmd.object_files = object_files;
|
||||
executable_link_cmd.output_exe = exe_name;
|
||||
|
||||
target.link_executable_commands.push_back(executable_link_cmd);
|
||||
|
||||
GState::get().targets.push_back(target);
|
||||
|
||||
return target_config;
|
||||
}
|
70
src/utils.cc
Normal file
70
src/utils.cc
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "grbc/helpers.h"
|
||||
#include "grbc/spec.h"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
|
||||
void grbc_exception(const std::string &exception_string) {
|
||||
printf("--- GRBC EXCEPTION: ---\n");
|
||||
printf("Message: %s\n", exception_string.c_str());
|
||||
printf("Timestamp: %ld", time(nullptr));
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void grbc_want_version(const std::string &version) {
|
||||
if (grbc_get_config().engine_version != version) {
|
||||
grbc_exception("Expected engine_version " + version + ", got " +
|
||||
grbc_get_config().engine_version);
|
||||
}
|
||||
}
|
||||
|
||||
std::string grbc_object_file(const std::string &file_path) {
|
||||
std::filesystem::path path(file_path);
|
||||
path.replace_extension(".o");
|
||||
|
||||
std::string path_str = path.generic_string();
|
||||
|
||||
// Strip out stuff
|
||||
std::string no_spaces = grbc_replace_string(path_str, ' ', '_');
|
||||
|
||||
return no_spaces;
|
||||
}
|
||||
|
||||
std::string grbc_replace_string(const std::string &string, char substring,
|
||||
char replacement) {
|
||||
|
||||
std::string res;
|
||||
|
||||
for (char cChar : string) {
|
||||
if (cChar == substring) {
|
||||
res += replacement;
|
||||
} else {
|
||||
res += cChar;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GlobalConfig grbc_get_config() {
|
||||
static GlobalConfig cfg{};
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
std::string grbc_include_dirs_to_cflags(const std::vector<std::string> &include_dirs) {
|
||||
std::string result;
|
||||
|
||||
for (auto &include_dir : include_dirs) {
|
||||
result += "-I" + include_dir + " ";
|
||||
}
|
||||
|
||||
result.pop_back(); // Remove trailing space
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void grbc_log(const std::string &message) {
|
||||
log_msg(message.c_str());
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue