extension work + static library linking

This commit is contained in:
Hunter 2024-09-28 10:16:00 -04:00
parent ffa0f40652
commit b6ee9d0dc3
20 changed files with 568 additions and 131 deletions

View file

@ -12,3 +12,39 @@ up
up
bt
q
r
q
r
up
up
up
up
up
up
up
up
bt
q
r
bt
q
r
bt
q
r
bt
q
q
r
up
up
up
:q
q
r
up
up
up
up
up
q

View file

@ -7,5 +7,5 @@ add_subdirectory("vendor/sol2")
include_directories("include")
include_directories("vendor/sol2/include")
add_executable(grbc src/main.cc src/utils.cc src/file.cc src/target_exe.cc src/platform.cc src/ninja.cc src/generator.cc)
add_executable(grbc src/main.cc src/utils.cc src/file.cc src/target_exe.cc src/platform.cc src/ninja.cc src/generator.cc src/target_lib.cc src/package.cc)
target_link_libraries(grbc sol2 lua)

47
HConfig
View file

@ -1,17 +1,44 @@
grbc_want_version("1.0")
grbc_load_platform("platform.hcfg")
grbc_load_profile("profile.hcfg")
local grbc_lib = grbc_library(LibraryConfig.new({
name = "libgrbc",
language_type = LanguageType.Cpp,
files = {
grbc_file("src/file.cc"),
grbc_file("src/ninja.cc"),
grbc_file("src/platform.cc"),
grbc_file("src/target_exe.cc"),
grbc_file("src/utils.cc"),
grbc_file("src/generator.cc"),
grbc_file("src/target_lib.cc"),
grbc_file("src/package.cc")
},
lib_type = LibraryType.Static,
requirements = {},
compile_flags = {},
linker_flags = {},
include_dirs = {
grbc_file("include"),
grbc_file("vendor/sol2/include")
},
package_config = PackageConfig.new({
name = "libgrbc",
libraries = {},
include_dirs = {},
compile_flags = {},
linker_flags = {},
})
}))
local grbc_exe = grbc_executable(ExecutableConfig.new({
name = "grbc",
language_type = LanguageType.Cpp,
files = {
grbc_file("src/main.cc"),
grbc_file("src/file.cc"),
grbc_file("src/ninja.cc"),
grbc_file("src/platform.cc"),
grbc_file("src/target_exe.cc"),
grbc_file("src/utils.cc"),
grbc_file("src/generator.cc")
},
requirements = {
@ -19,9 +46,13 @@ local grbc_exe = grbc_executable(ExecutableConfig.new({
name = "lua",
compiler_flags = "",
linker_flags = "-llua -lm -ldl"
})
}),
grbc_pkg("libgrbc")
},
compile_flags = {
grbc_compiler_define("HCONFIG", "")
},
compile_flags = {},
linker_flags = {},
include_dirs = {
grbc_file("include"),

View file

@ -2,4 +2,11 @@
GRaphite Build Configurator
## About
GRBC is a predictable build system.
GRBC was developed because I hate CMake. I liked the build systems built for zig, and jai, but wanted something for C++. I also enjoyed how Vulkan extensions were managed and took insipiration from them to make grbc extensible.
## Benifits
* GRBC is fast, almost no wait time for build.ninja generation
* GRBC scripts are easy to read, and predictable
* GRBC produces ninja files which can be ran without grbc installed
* GRBC has cmake interop, so libraries using cmake can still be used
* GRBC is well documented

View file

@ -26,18 +26,19 @@ rule cxx
rule link_cc
command = $cc_path $p_cflags -o $out $in $p_linker_flags
description = Linking C executables $out
description = Linking C target $out
## build_rule_link_cxx ##
rule link_cxx
command = $cxx_path $p_cflags -o $out $in $p_linker_flags
description = Linking C++ executables $out
description = Linking C++ target $out
## Compile: src/main.cc ##
## build_rule_archive_library ##
build $builddir/src/main.o: cxx src/main.cc
p_cflags = -Iinclude -Ivendor/sol2/include
rule archive
command = rm -f $out; ar crs $out $in
description = Creating static library $out
## Compile: src/file.cc ##
@ -69,9 +70,28 @@ build $builddir/src/utils.o: cxx src/utils.cc
build $builddir/src/generator.o: cxx src/generator.cc
p_cflags = -Iinclude -Ivendor/sol2/include
## Compile: src/target_lib.cc ##
build $builddir/src/target_lib.o: cxx src/target_lib.cc
p_cflags = -Iinclude -Ivendor/sol2/include
## Compile: src/package.cc ##
build $builddir/src/package.o: cxx src/package.cc
p_cflags = -Iinclude -Ivendor/sol2/include
## Link: libgrbc.a ##
build $builddir/libgrbc.a: archive $builddir/src/file.o $builddir/src/ninja.o $builddir/src/platform.o $builddir/src/target_exe.o $builddir/src/utils.o $builddir/src/generator.o $builddir/src/target_lib.o $builddir/src/package.o
## Compile: src/main.cc ##
build $builddir/src/main.o: cxx src/main.cc
p_cflags = -fdiagnostics-color=always -DHCONFIG= -Iinclude -Ivendor/sol2/include
## Link: grbc ##
build grbc: link_cxx $builddir/src/main.o $builddir/src/file.o $builddir/src/ninja.o $builddir/src/platform.o $builddir/src/target_exe.o $builddir/src/utils.o $builddir/src/generator.o
p_linker_flags = -llua -lm -ldl
build $builddir/grbc: link_cxx $builddir/src/main.o
p_linker_flags = -llua -lm -ldl build/libgrbc.a
p_cflags =

View file

@ -7,49 +7,49 @@
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/main.cc.o -MF CMakeFiles/grbc.dir/src/main.cc.o.d -o CMakeFiles/grbc.dir/src/main.cc.o -c /home/interfiber/dev/grbc/src/main.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/main.cc.o -MF CMakeFiles/grbc.dir/src/main.cc.o.d -o CMakeFiles/grbc.dir/src/main.cc.o -c /home/interfiber/dev/grbc/src/main.cc",
"file": "/home/interfiber/dev/grbc/src/main.cc",
"output": "CMakeFiles/grbc.dir/src/main.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/utils.cc.o -MF CMakeFiles/grbc.dir/src/utils.cc.o.d -o CMakeFiles/grbc.dir/src/utils.cc.o -c /home/interfiber/dev/grbc/src/utils.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/utils.cc.o -MF CMakeFiles/grbc.dir/src/utils.cc.o.d -o CMakeFiles/grbc.dir/src/utils.cc.o -c /home/interfiber/dev/grbc/src/utils.cc",
"file": "/home/interfiber/dev/grbc/src/utils.cc",
"output": "CMakeFiles/grbc.dir/src/utils.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/file.cc.o -MF CMakeFiles/grbc.dir/src/file.cc.o.d -o CMakeFiles/grbc.dir/src/file.cc.o -c /home/interfiber/dev/grbc/src/file.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/file.cc.o -MF CMakeFiles/grbc.dir/src/file.cc.o.d -o CMakeFiles/grbc.dir/src/file.cc.o -c /home/interfiber/dev/grbc/src/file.cc",
"file": "/home/interfiber/dev/grbc/src/file.cc",
"output": "CMakeFiles/grbc.dir/src/file.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/target_exe.cc.o -MF CMakeFiles/grbc.dir/src/target_exe.cc.o.d -o CMakeFiles/grbc.dir/src/target_exe.cc.o -c /home/interfiber/dev/grbc/src/target_exe.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/target_exe.cc.o -MF CMakeFiles/grbc.dir/src/target_exe.cc.o.d -o CMakeFiles/grbc.dir/src/target_exe.cc.o -c /home/interfiber/dev/grbc/src/target_exe.cc",
"file": "/home/interfiber/dev/grbc/src/target_exe.cc",
"output": "CMakeFiles/grbc.dir/src/target_exe.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/platform.cc.o -MF CMakeFiles/grbc.dir/src/platform.cc.o.d -o CMakeFiles/grbc.dir/src/platform.cc.o -c /home/interfiber/dev/grbc/src/platform.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/platform.cc.o -MF CMakeFiles/grbc.dir/src/platform.cc.o.d -o CMakeFiles/grbc.dir/src/platform.cc.o -c /home/interfiber/dev/grbc/src/platform.cc",
"file": "/home/interfiber/dev/grbc/src/platform.cc",
"output": "CMakeFiles/grbc.dir/src/platform.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/ninja.cc.o -MF CMakeFiles/grbc.dir/src/ninja.cc.o.d -o CMakeFiles/grbc.dir/src/ninja.cc.o -c /home/interfiber/dev/grbc/src/ninja.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/ninja.cc.o -MF CMakeFiles/grbc.dir/src/ninja.cc.o.d -o CMakeFiles/grbc.dir/src/ninja.cc.o -c /home/interfiber/dev/grbc/src/ninja.cc",
"file": "/home/interfiber/dev/grbc/src/ninja.cc",
"output": "CMakeFiles/grbc.dir/src/ninja.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -g -MD -MT CMakeFiles/grbc.dir/src/generator.cc.o -MF CMakeFiles/grbc.dir/src/generator.cc.o.d -o CMakeFiles/grbc.dir/src/generator.cc.o -c /home/interfiber/dev/grbc/src/generator.cc",
"command": "/usr/lib64/ccache/g++ -I/home/interfiber/dev/grbc/include -isystem /home/interfiber/dev/grbc/vendor/sol2/include -O2 -g -DNDEBUG -MD -MT CMakeFiles/grbc.dir/src/generator.cc.o -MF CMakeFiles/grbc.dir/src/generator.cc.o.d -o CMakeFiles/grbc.dir/src/generator.cc.o -c /home/interfiber/dev/grbc/src/generator.cc",
"file": "/home/interfiber/dev/grbc/src/generator.cc",
"output": "CMakeFiles/grbc.dir/src/generator.cc.o"
},
{
"directory": "/home/interfiber/dev/grbc/build",
"command": ": && /usr/lib64/ccache/g++ -g CMakeFiles/grbc.dir/src/main.cc.o CMakeFiles/grbc.dir/src/utils.cc.o CMakeFiles/grbc.dir/src/file.cc.o CMakeFiles/grbc.dir/src/target_exe.cc.o CMakeFiles/grbc.dir/src/platform.cc.o CMakeFiles/grbc.dir/src/ninja.cc.o CMakeFiles/grbc.dir/src/generator.cc.o -o grbc -llua && :",
"command": ": && /usr/lib64/ccache/g++ -O2 -g -DNDEBUG CMakeFiles/grbc.dir/src/main.cc.o CMakeFiles/grbc.dir/src/utils.cc.o CMakeFiles/grbc.dir/src/file.cc.o CMakeFiles/grbc.dir/src/target_exe.cc.o CMakeFiles/grbc.dir/src/platform.cc.o CMakeFiles/grbc.dir/src/ninja.cc.o CMakeFiles/grbc.dir/src/generator.cc.o -o grbc -llua && :",
"file": "CMakeFiles/grbc.dir/src/main.cc.o",
"output": "grbc"
},

3
include/grbc/ext.h Normal file
View file

@ -0,0 +1,3 @@
#pragma once
#define GRBC_EXT_pkg_config_NAME "GRBC_EXT_pkg_config"

View file

@ -3,6 +3,12 @@
#include <string>
#include <vector>
enum GeneratorTargetType {
GeneratorTargetType_Executable,
GeneratorTargetType_SharedLibrary,
GeneratorTargetType_StaticLibrary
};
struct GeneratorResult {
std::string file_name;
std::string content;
@ -17,17 +23,18 @@ struct GeneratorCompileCommand {
std::string compiler_flags;
};
struct GeneratorLinkExecutableCommand {
struct GeneratorLinkTargetCommand {
std::vector<std::string> object_files;
std::string output_exe;
std::string linker_flags;
std::string output_name;
GeneratorTargetType target_type;
};
struct GeneratorTarget {
std::vector<GeneratorCompileCommand> compile_commands;
std::vector<GeneratorLinkExecutableCommand> link_executable_commands;
std::vector<GeneratorLinkTargetCommand> link_target_commands;
};
typedef GeneratorResult (*Generator_Run)();

View file

@ -22,6 +22,11 @@ std::string ninja_build_rule_link_cxx();
*/
std::string ninja_build_rule_link_cc();
/**
* Generate the build rule for archiving object files into a shared library
*/
std::string ninja_build_rule_archive_library();
/**
* Generate a line which builds the given file
*/
@ -34,7 +39,13 @@ ninja_build_rule_compile_file(const GeneratorCompileCommand &compile_cmd);
std::string ninja_build_default_variables();
/**
* Generate a line which links the given file
* Generate a line which links the given file to an executable
*/
std::string ninja_build_rule_link_exe_target(
const GeneratorLinkExecutableCommand &link_cmd);
std::string
ninja_build_rule_link_exe_target(const GeneratorLinkTargetCommand &link_cmd);
/**
* Generate a line which links the given file to a library
*/
std::string
ninja_build_rule_link_lib_target(const GeneratorLinkTargetCommand &link_cmd);

View file

@ -1,11 +1,13 @@
#pragma once
#include <sol/table.hpp>
#include <sol/types.hpp>
#include <string>
#include <vector>
#define GRBC_VERSION "1.0"
enum LanguageType { LanguageType_CPP, LanguageType_C };
enum LibraryType { LibraryType_Shared, LibraryType_Static };
struct TargetInfo {
/// Name of the target
@ -19,6 +21,8 @@ struct Package {
linker_flags = table.get<std::string>("linker_flags");
}
Package() = default;
std::string name;
std::string compiler_flags;
@ -27,6 +31,16 @@ struct Package {
};
struct PackageConfig {
PackageConfig(const sol::table &table) {
name = table.get<std::string>("name");
libraries = table.get<std::vector<Package>>("libraries");
include_dirs = table.get<std::vector<std::string>>("include_dirs");
compile_flags = table.get<std::vector<std::string>>("compile_flags");
linker_flags = table.get<std::vector<std::string>>("linker_flags");
}
PackageConfig() = default;
std::string name;
std::vector<Package> libraries;
@ -50,21 +64,21 @@ struct GlobalConfig {
/// Build directory
std::string build_dir = "build";
/// System that we are targetting
PlatformType target;
/// Path to the target.hcfg
std::string target_config;
/// Path to the platform.hcfg, in_memory if not on-disk
std::string platform_config;
};
struct ExecutableConfig {
ExecutableConfig(const sol::table &table) {
name = table.get<std::string>("name");
files = table.get<std::vector<std::string>>("files");
requirements = table.get<std::vector<Package>>("requirements");
compile_flags = table.get<std::vector<std::string>>("compile_flags");
linker_flags = table.get<std::vector<std::string>>("linker_flags");
include_dirs = table.get<std::vector<std::string>>("include_dirs");
language_type = table.get<LanguageType>("language_type");
@ -77,19 +91,67 @@ struct ExecutableConfig {
LanguageType language_type;
/// List of files to compile
std::vector<std::string> files;
std::vector<std::string> files{};
/// Requirments of the executable
std::vector<Package> requirements;
std::vector<Package> requirements{};
/// Compiler flags
std::vector<std::string> compile_flags;
std::vector<std::string> compile_flags{};
/// Linker flags
std::vector<std::string> linker_flags;
std::vector<std::string> linker_flags{};
/// Include directories
std::vector<std::string> include_dirs;
std::vector<std::string> include_dirs{};
};
struct LibraryConfig {
LibraryConfig(const sol::table &table) {
name = table.get<std::string>("name");
files = table.get<std::vector<std::string>>("files");
requirements = table.get<std::vector<Package>>("requirements");
compile_flags = table.get<std::vector<std::string>>("compile_flags");
linker_flags = table.get<std::vector<std::string>>("linker_flags");
include_dirs = table.get<std::vector<std::string>>("include_dirs");
language_type = table.get<LanguageType>("language_type");
lib_type = table.get<LibraryType>("lib_type");
if (!table["package_config"].is<sol::nil_t>())
package_config = table.get<PackageConfig>("package_config");
}
/// Name of the executable
std::string name;
/// Type of language
LanguageType language_type;
/// Type of library
LibraryType lib_type;
/// Package config
PackageConfig package_config{};
/// List of files to compile
std::vector<std::string> files{};
/// Requirments of the executable
std::vector<Package> requirements{};
/// Compiler flags
std::vector<std::string> compile_flags{};
/// Linker flags
std::vector<std::string> linker_flags{};
/// Include directories
std::vector<std::string> include_dirs{};
};
struct Platform {
@ -115,12 +177,14 @@ void grbc_want_version(const std::string &version);
void grbc_exception(const std::string &exception_string);
GlobalConfig grbc_get_config();
GlobalConfig& grbc_get_config();
std::string grbc_file(const std::string &file_path);
TargetInfo grbc_executable(const ExecutableConfig &executable_config);
TargetInfo grbc_library(const LibraryConfig &library_config);
void grbc_load_platform(const std::string &file_path);
void grbc_set_platform(const Platform &platform);
@ -148,3 +212,12 @@ PlatformType grbc_get_platform();
bool grbc_is_64bit();
bool grbc_is_32bit();
std::string grbc_compiler_define(const std::string &define,
const std::string &value);
std::string grbc_get_lib_extension(LibraryType lib_type);
Package grbc_bake_package_config(const PackageConfig &config);
Package grbc_pkg(const std::string &package_name);

View file

@ -2,15 +2,18 @@
#include "grbc/generator.h"
#include "grbc/spec.h"
#include <sol/sol.hpp>
#include <string>
#include <unordered_map>
struct GState {
Platform current_platform;
sol::state lua;
std::vector<GeneratorTarget> targets;
std::vector<Generator> generators;
std::unordered_map<std::string, Package> packages;
std::string ninja_output;
static GState& get() {

View file

@ -46,6 +46,9 @@ struct LibraryConfig {
/// Type of library
LibraryType lib_type;
/// Package config for the library, leave empty to disable
PackageConfig package_config{};
/// Requirments of the library
Array<Package> requirements;
@ -125,8 +128,8 @@ struct GlobalConfig {
/// Platform to target (pulled from the target config)
PlatformTarget target;
/// Path to the target.hcfg
path target_config;
/// Path to the platform.hcfg, in_memory if not on-disk
string platform_config;
};
```
@ -151,6 +154,9 @@ struct Platform {
/// C compiler
string cc_compiler;
/// Do these compilers produce 32bit code?
bool is_64bit;
/// Type of the platform
PlatformType platform_type;
};
@ -163,3 +169,13 @@ enum LanguageType {
LanguageType_C
};
```
## Profile
```c++
struct Profile {
string name;
Array<string> compiler_flags;
Array<string> linker_flags;
};
```

View file

@ -2,7 +2,7 @@
See [datatypes.md](./datatypes.md) for data types/structures
## [X] grbc_get_config() -> GlobalConfig
Get the config
Get the config as as read-write reference
## [X] grbc_want_version(version: String) -> Void
Assure grbc is running on ```version```
@ -28,11 +28,11 @@ Check if we are targeting a 32bit system
## [X] grbc_executable(executable_config: ExecutableConfig) -> TargetInfo
Create a new executable and add it to the build list
## grbc_library(library_config: LibraryConfig) -> TargetInfo
## [X] grbc_library(library_config: LibraryConfig) -> TargetInfo
Create a new library and add it to the build list
## [X] grbc_create_package(package_config: PackageConfig) -> Package
Create a new package
## grbc_pkg(package_name: String) -> Package
Get a package with the given name and return its baked form
## [X] grbc_file(file_path: String) -> Path
Used when listing source files, should perform pre-checks on the file and return its path
@ -69,3 +69,12 @@ Replace substring in string with replacement
## [X] grbc_include_dirs_to_cflags(include_dirs: Array<String>) -> String
Generate compiler flags to include the given directories
## [X] grbc_compiler_define(define: String, value: String) -> String
Generate a compiler flag to define a variable
## [X] grbc_get_lib_extension(library_type: LibraryType) -> String
Get the given extension for a library file on the current platform
## [X] grbc_bake_package_config(config: PackageConfig) -> Package
Convert a PackageConfig into a Package

View file

@ -20,7 +20,7 @@ int main() {
// PackageConfig
lua.new_usertype<PackageConfig>(
"PackageConfig", "name", &PackageConfig::name, "libraries",
"PackageConfig", sol::constructors<PackageConfig(sol::table)>(), "name", &PackageConfig::name, "libraries",
&PackageConfig::libraries, "include_dirs", &PackageConfig::include_dirs,
"compile_flags", &PackageConfig::compile_flags, "linker_flags",
&PackageConfig::linker_flags);
@ -28,36 +28,51 @@ int main() {
// GlobalConfig
lua.new_usertype<GlobalConfig>(
"GlobalConfig", "engine_version", &GlobalConfig::engine_version,
"architecture", &GlobalConfig::architecture, "target",
&GlobalConfig::target, "target_config", &GlobalConfig::target_config);
"architecture", &GlobalConfig::architecture, "target_config", &GlobalConfig::platform_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);
"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 }
});
lua.new_enum<LanguageType>(
"LanguageType", {{"Cpp", LanguageType_CPP}, {"C", LanguageType_C}});
// LibraryType
lua.new_enum<LibraryType>("LibraryType", {{"Static", LibraryType_Static},
{"Shared", LibraryType_Shared}});
// ExecutableConfig
lua.new_usertype<ExecutableConfig>(
"ExecutableConfig", sol::constructors<ExecutableConfig(sol::table)>(),
"name", &ExecutableConfig::name, "files", &ExecutableConfig::files,
"requirments", &ExecutableConfig::requirements, "compile_flags",
"requirements", &ExecutableConfig::requirements, "compile_flags",
&ExecutableConfig::compile_flags, "linker_flags",
&ExecutableConfig::linker_flags, "include_dirs",
&ExecutableConfig::include_dirs, "language_type", &ExecutableConfig::language_type);
&ExecutableConfig::include_dirs, "language_type",
&ExecutableConfig::language_type);
// LibraryConfig
lua.new_usertype<LibraryConfig>(
"LibraryConfig", sol::constructors<LibraryConfig(sol::table)>(), "name",
&LibraryConfig::name, "files", &LibraryConfig::files, "requirements",
&LibraryConfig::requirements, "compile_flags",
&LibraryConfig::compile_flags, "linker_flags",
&LibraryConfig::linker_flags, "include_dirs",
&LibraryConfig::include_dirs, "language_type",
&LibraryConfig::language_type, "lib_type", &LibraryConfig::lib_type,
"package_config", &LibraryConfig::package_config);
// Package
lua.new_usertype<Package>("Package", sol::constructors<Package(sol::table)>(), "name", &Package::name, "compiler_flags",
lua.new_usertype<Package>("Package", sol::constructors<Package(sol::table)>(),
"name", &Package::name, "compiler_flags",
&Package::compiler_flags, "linker_flags",
&Package::linker_flags);
@ -66,6 +81,7 @@ int main() {
lua.set("grbc_get_config", grbc_get_config);
lua.set("grbc_file", grbc_file);
lua.set("grbc_executable", grbc_executable);
lua.set("grbc_library", grbc_library);
lua.set("grbc_load_platform", grbc_load_platform);
lua.set("grbc_set_platform", grbc_set_platform);
lua.set("grbc_find_compiler", grbc_find_compiler);
@ -79,13 +95,15 @@ int main() {
lua.set("grbc_is_linux", grbc_is_linux);
lua.set("grbc_is_win32", grbc_is_win32);
lua.set("grbc_get_platform", grbc_get_platform);
lua.set("grbc_compiler_define", grbc_compiler_define);
lua.set("grbc_get_lib_extension", grbc_get_lib_extension);
lua.set("grbc_bake_package_config", grbc_bake_package_config);
lua.set("grbc_pkg", grbc_pkg);
// Load generators
GState::get().generators.push_back({
.name = "ninja",
.func = ninja_generator
});
GState::get().generators.push_back(
{.name = "ninja", .func = ninja_generator});
log_msg("loading HConfig...");

View file

@ -40,7 +40,7 @@ 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";
result += " description = Linking C++ target $out\n\n";
return result;
}
@ -49,7 +49,16 @@ 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";
result += " description = Linking C target $out\n\n";
return result;
}
std::string ninja_build_rule_archive_library() {
std::string result = "## build_rule_archive_library ##\n\n";
result += "rule archive\n";
result += " command = rm -f $out; ar crs $out $in\n";
result += " description = Creating static library $out\n\n";
return result;
}
@ -79,9 +88,9 @@ std::string ninja_build_default_variables() {
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
ninja_build_rule_link_lib_target(const GeneratorLinkTargetCommand &link_cmd) {
std::string result = "## Link: " + link_cmd.output_name + " ##\n\n";
std::string file_list;
@ -91,7 +100,34 @@ std::string ninja_build_rule_link_exe_target(
file_list.pop_back();
result += "build " + link_cmd.output_exe + ": link_cxx " + file_list + "\n";
if (link_cmd.target_type == GeneratorTargetType_SharedLibrary) {
result += "build $builddir/" + link_cmd.output_name + ": link_cxx " +
file_list + "\n";
result += " p_linker_flags = " + link_cmd.linker_flags + " -shared\n";
result += " p_cflags = \n\n";
} else {
result += "build $builddir/" + link_cmd.output_name + ": archive " +
file_list + "\n\n";
}
return result;
}
std::string
ninja_build_rule_link_exe_target(const GeneratorLinkTargetCommand &link_cmd) {
std::string result = "## Link: " + link_cmd.output_name + " ##\n\n";
std::string file_list;
for (auto &file : link_cmd.object_files) {
file_list += "$builddir/" + file + " ";
}
file_list.pop_back();
result += "build $builddir/" + link_cmd.output_name + ": link_cxx " +
file_list + "\n";
result += " p_linker_flags = " + link_cmd.linker_flags + "\n";
result += " p_cflags = \n\n";
@ -113,14 +149,19 @@ GeneratorResult ninja_generator() {
result.content += ninja_build_rule_compile_cxx();
result.content += ninja_build_rule_link_cc();
result.content += ninja_build_rule_link_cxx();
result.content += ninja_build_rule_archive_library();
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) {
for (auto &link_cmd : target.link_target_commands) {
if (link_cmd.target_type == GeneratorTargetType_Executable) {
result.content += ninja_build_rule_link_exe_target(link_cmd);
} else {
result.content += ninja_build_rule_link_lib_target(link_cmd);
}
}
}

42
src/package.cc Normal file
View file

@ -0,0 +1,42 @@
#include "grbc/spec.h"
#include "grbc/state.h"
Package grbc_pkg(const std::string &package_name) {
for (auto &pkg : GState::get().packages) {
if (pkg.first == package_name) return pkg.second;
}
grbc_exception("Could not find package with name '" + package_name + "'");
return Package{};
}
Package grbc_bake_package_config(const PackageConfig &config) {
Package pkg{};
pkg.name = config.name;
// Generate list of compiler + linker arguments
for (auto &subpkg : config.libraries) {
pkg.compiler_flags += subpkg.compiler_flags + " ";
pkg.linker_flags += subpkg.linker_flags + " ";
}
for (auto &linker_flag : config.linker_flags) {
pkg.linker_flags += linker_flag + " ";
}
for (auto &compiler_flag : config.compile_flags) {
pkg.compiler_flags += compiler_flag + " ";
}
// Remove trailing whitespace
if (pkg.compiler_flags.back() == ' ')
pkg.compiler_flags.pop_back();
if (pkg.linker_flags.back() == ' ')
pkg.linker_flags.pop_back();
return pkg;
}

View file

@ -21,12 +21,16 @@ void grbc_set_platform(const Platform &platform) {
log_msg(("C++ compiler = " + platform.cxx_compiler).c_str());
log_msg(("C compiler = " + platform.cc_compiler).c_str());
grbc_get_config().platform_config = "in_memory";
}
void grbc_load_platform(const std::string &file_path) {
Platform platform = GState::get().lua.script_file(file_path);
grbc_set_platform(platform);
grbc_get_config().platform_config = file_path;
}
std::string grbc_find_compiler(const std::string &compiler_name) {

View file

@ -6,6 +6,10 @@ TargetInfo grbc_executable(const ExecutableConfig &executable_config) {
TargetInfo target_config{};
std::string exe_name = executable_config.name;
if (grbc_is_win32())
exe_name += ".exe";
std::string compiler_args;
std::string linker_args;
@ -44,12 +48,13 @@ TargetInfo grbc_executable(const ExecutableConfig &executable_config) {
// Final executable link
GeneratorLinkExecutableCommand executable_link_cmd{};
GeneratorLinkTargetCommand executable_link_cmd{};
executable_link_cmd.linker_flags = linker_args;
executable_link_cmd.object_files = object_files;
executable_link_cmd.output_exe = exe_name;
executable_link_cmd.output_name = exe_name;
executable_link_cmd.target_type = GeneratorTargetType_Executable;
target.link_executable_commands.push_back(executable_link_cmd);
target.link_target_commands.push_back(executable_link_cmd);
GState::get().targets.push_back(target);

81
src/target_lib.cc Normal file
View file

@ -0,0 +1,81 @@
#include "grbc/generator.h"
#include "grbc/spec.h"
#include "grbc/state.h"
TargetInfo grbc_library(const LibraryConfig &library_config) {
TargetInfo target_config{};
std::string lib_name = library_config.name;
lib_name += grbc_get_lib_extension(library_config.lib_type);
std::string compiler_args;
std::string linker_args;
for (auto &package : library_config.requirements) {
compiler_args += package.compiler_flags + " ";
linker_args += package.linker_flags + " ";
}
for (auto &linker_arg : library_config.linker_flags) {
linker_args += linker_arg + " ";
}
for (auto &compiler_arg : library_config.compile_flags) {
compiler_args += compiler_arg + " ";
}
// Include directories
compiler_args += grbc_include_dirs_to_cflags(library_config.include_dirs);
GeneratorTarget target{};
std::vector<std::string> object_files;
for (auto &src_file : library_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 = library_config.language_type;
object_files.push_back(compile_cmd.object_file);
target.compile_commands.push_back(compile_cmd);
}
// Generate package config
PackageConfig pkg_cfg{};
pkg_cfg.name = library_config.name;
pkg_cfg.libraries = library_config.package_config.libraries;
pkg_cfg.include_dirs = library_config.include_dirs;
if (library_config.lib_type == LibraryType_Static) {
pkg_cfg.linker_flags.push_back(grbc_get_config().build_dir + "/" + lib_name);
}
// FIXME: Shared library linker flags
if (!pkg_cfg.name.empty()) {
GState::get().packages.insert(
{pkg_cfg.name, grbc_bake_package_config(pkg_cfg)});
}
GeneratorLinkTargetCommand link_target{};
if (library_config.lib_type == LibraryType_Shared) {
link_target.target_type = GeneratorTargetType_SharedLibrary;
} else {
link_target.target_type = GeneratorTargetType_StaticLibrary;
}
link_target.object_files = object_files;
link_target.linker_flags = linker_args;
link_target.output_name = lib_name;
target.link_target_commands.push_back(link_target);
GState::get().targets.push_back(target);
return target_config;
}

View file

@ -1,5 +1,6 @@
#include "grbc/helpers.h"
#include "grbc/spec.h"
#include "grbc/state.h"
#include <cstdlib>
#include <ctime>
#include <filesystem>
@ -47,13 +48,17 @@ std::string grbc_replace_string(const std::string &string, char substring,
return res;
}
GlobalConfig grbc_get_config() {
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
grbc_include_dirs_to_cflags(const std::vector<std::string> &include_dirs) {
if (include_dirs.empty())
return "";
std::string result;
for (auto &include_dir : include_dirs) {
@ -65,6 +70,31 @@ std::string grbc_include_dirs_to_cflags(const std::vector<std::string> &include_
return result;
}
void grbc_log(const std::string &message) {
log_msg(message.c_str());
void grbc_log(const std::string &message) { log_msg(message.c_str()); }
std::string grbc_compiler_define(const std::string &define,
const std::string &value) {
return "-D" + define + "=" + value;
}
std::string grbc_get_lib_extension(LibraryType lib_type) {
PlatformType platform_type = GState::get().current_platform.platform_type;
if (platform_type == PlatformType_Linux && lib_type == LibraryType_Shared) {
return ".so";
} else if (platform_type == PlatformType_Linux &&
lib_type == LibraryType_Static) {
return ".a";
} else if (platform_type == PlatformType_Win32 &&
lib_type == LibraryType_Shared) {
return ".dll";
} else if (platform_type == PlatformType_Win32 &&
lib_type == LibraryType_Static) {
return ".lib";
}
grbc_exception("Could not determine library extension for current platform + "
"library combo");
return "";
}