summaryrefslogtreecommitdiff
path: root/src/libctor.h
blob: 721ac6a7d1f3f990b5190379d105edf6de53a474 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// -*- c++ -*-
// Distributed under the BSD 2-Clause License.
// See accompanying file LICENSE for details.
#pragma once

#include <source_location>
#include <string>
#include <vector>
#include <map>
#include <variant>

enum class TargetType
{
	Auto, // Default - deduce from target name and sources extensions

	Executable,
	StaticLibrary,
	DynamicLibrary,
	Object,
	UnitTest,
};

enum class Language
{
	Auto, // Default - deduce language from source extensions

	C,
	Cpp,
	Asm,
};

enum class OutputSystem
{
	Host, // Output for the target system
	Build, // Internal tool during cross-compilation
};

struct Source
{
	Source(const char* file) : file(file) {}
	Source(const std::string& file) : file(file) {}
	Source(const char* file, Language lang) : file(file), language(lang) {}
	Source(const std::string& file, Language lang) : file(file), language(lang) {}

	std::string file;
	Language language{Language::Auto};
};

struct Flags
{
	std::vector<std::string> cxxflags; // flags for c++ compiler
	std::vector<std::string> cflags; // flags for c compiler
	std::vector<std::string> ldflags; // flags for linker
	std::vector<std::string> asmflags; // flags for asm translator
};

struct BuildConfiguration
{
	std::string name; // Name - used for referring in other configurations.
	TargetType type{TargetType::Auto};
	OutputSystem system{OutputSystem::Host};
	std::string target; // Output target file for this configuration
	std::vector<Source> sources; // source list
	std::vector<std::string> depends; // internal target dependencies
	Flags flags;
	std::vector<std::string> externals; // externals used by this configuration
};

using BuildConfigurations = std::vector<BuildConfiguration>;

int reg(BuildConfigurations (*cb)(),
        const std::source_location location = std::source_location::current());

// This type will use flags verbatim
struct ExternalManual
{
	Flags flags;
};


struct ExternalConfiguration
{
	std::string name; // Name for configuration
	std::variant<ExternalManual> external;
};

using ExternalConfigurations = std::vector<ExternalConfiguration>;

int reg(ExternalConfigurations (*cb)(),
        const std::source_location location = std::source_location::current());

// Convenience macro - ugly but keeps things simple(r)
#define CONCAT(a, b) CONCAT_INNER(a, b)
#define CONCAT_INNER(a, b) a ## b
#define UNIQUE_NAME(base) CONCAT(base, __LINE__)
#define REG(cb) namespace { int UNIQUE_NAME(unique) = reg(cb); }

// Predefined configuration keys
namespace cfg
{
constexpr auto builddir = "builddir";

constexpr auto host_cc = "host-cc";
constexpr auto host_cxx = "host-cpp";
constexpr auto host_ar = "host-ar";
constexpr auto host_ld = "host-ld";

constexpr auto build_cc = "build-cc";
constexpr auto build_cxx = "build-cpp";
constexpr auto build_ar = "build-ar";
constexpr auto build_ld = "build-ld";

constexpr auto ctor_includedir = "ctor-includedir";
constexpr auto ctor_libdir = "ctor-libdir";
}

struct Configuration
{
	std::vector<std::string> args; // vector of arguments used when last calling configure
	std::map<std::string, std::string> env; // env used when last calling configure

	std::map<std::string, std::string> tools; // tools
	std::map<std::string, Flags> externals;
};

const Configuration& configuration();
bool hasConfiguration(const std::string& key);
const std::string& getConfiguration(const std::string& key,
                                    const std::string& defaultValue = {});