-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_conf_parser.cc
231 lines (177 loc) · 9.08 KB
/
build_conf_parser.cc
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include <chrono>
#include <filesystem>
#include <fs_utils.h>
#include <journal.h>
#include <yaml-cpp/yaml.h>
#include "common.h"
#include "config.h"
#include "context.h"
namespace fs = std::filesystem;
namespace fs_utils = filesystem_utils;
namespace app {
namespace bs {
constexpr char CONF_PROJECT_NAME[] = "project";
constexpr char CONF_CXX_FLAGS[] = "cxx-flags";
constexpr char CONF_CXX_COMPILLER[] = "cxx-compiler";
constexpr char CONF_TARGET_LIST[] = "build";
constexpr char CONF_TARGET_NAME[] = "name";
constexpr char CONF_TARGET_SOURES[] = "sources";
constexpr char CONF_TARGET_TYPE[] = "type";
constexpr char CONF_TARGET_RPATH[] = "rpath";
constexpr char CONF_TARGET_LINK_LIBRARIES[] = "libaries";
constexpr char CONF_ALL_TAG[] = "all";
constexpr char CONF_PROFILE_TAG[] = "profile";
constexpr char CONF_PROFILE_DEBUG[] = "DEBUG";
constexpr char CONF_PROFILE_RELEASE[] = "RELEASE";
constexpr char CXX_FLAG_SUPPURT_CXX17[] = "c++17";
constexpr char CXX_FLAG_ALL_WARNINGS[] = "all-warnings";
// constexpr char CXX_COMPLIER_LATEST[] = "latest";
static auto get_build_type( std::string_view value ) {
if ( value == common::TARGET_TYPE_APP )
return target_build_type::BINARY_APPLICATION;
if ( value == common::TARGET_TYPE_STATIC_LIB )
return target_build_type::STATIC_LIBRARY;
if ( value == common::TARGET_TYPE_SHARED_LIB )
return target_build_type::SHARED_LIBRARY;
return target_build_type::BINARY_UNKNOWN;
}
static auto make_application_name( std::string_view name ) {
return name;
}
static auto make_static_library_name( std::string_view name ) {
std::string lib_name;
if ( name.compare( 1, 3, "lib" ) == 0 )
lib_name += "lib";
lib_name += name;
lib_name += ".a";
return lib_name;
}
static auto make_shared_library_name( std::string_view name ) {
std::string lib_name;
if ( name.compare( 1, 3, "lib" ) == 0 )
lib_name += "lib";
lib_name += name;
lib_name += ".so";
return lib_name;
}
static auto append_sub_target( bs::context &ctx, const YAML::Node &conf, bs::target ¤t_target ) -> bool;
static auto append_sub_target( bs::context &ctx, const YAML::Node &conf, bs::target ¤t_target ) -> bool {
using namespace std;
if ( !ctx.build_path.empty( ) ) {
const auto target_name = conf[CONF_TARGET_NAME].as<string>( );
const auto target_path = ctx.base_path;
const auto target_type = conf[CONF_TARGET_TYPE].as<string>( );
const auto target_runtime_path = conf[CONF_TARGET_RPATH] ? conf[CONF_TARGET_RPATH].as<string>( ) : string{};
vector<string> target_sources;
if ( conf[CONF_TARGET_SOURES].IsScalar( ) ) {
const auto sources_value = conf[CONF_TARGET_SOURES].as<string>( );
if ( sources_value == CONF_ALL_TAG ) {
const auto sources_path = string{target_path} + fs::path::preferred_separator + common::DEFAULT_SOURCE_DIR +
fs::path::preferred_separator + target_name;
std::error_code err;
if ( !fs::exists( sources_path, err ) ) {
LOG_WARNING( APP_TAG, "Source path not exists %1", sources_path );
}
const auto &extensions = ctx.cxx_extensions;
target_sources = fs_utils::get_directory_files_by_ext( sources_path, extensions );
}
} else if ( conf[CONF_TARGET_SOURES].IsSequence( ) ) {
target_sources = conf[CONF_TARGET_SOURES].as<vector<string>>( );
std::error_code err;
for ( auto &s : target_sources ) {
if ( !s.empty( ) && !fs::exists( s, err ) ) {
const auto sources_path = string{target_path} + fs::path::preferred_separator + common::DEFAULT_SOURCE_DIR +
fs::path::preferred_separator + target_name + fs::path::preferred_separator + s;
if ( fs::exists( sources_path, err ) )
s = sources_path;
}
}
}
current_target.name = target_name;
current_target.sources = target_sources;
current_target.type = get_build_type( target_type );
current_target.run_time_path = target_runtime_path;
if ( conf[CONF_TARGET_LINK_LIBRARIES] ) {
current_target.link_libraries = conf[CONF_TARGET_LINK_LIBRARIES].as<std::vector<string>>( );
}
switch ( current_target.type ) {
case target_build_type::BINARY_UNKNOWN:
current_target.output = current_target.name;
break;
case target_build_type::BINARY_APPLICATION:
current_target.output = make_application_name( current_target.name );
break;
case target_build_type::STATIC_LIBRARY:
current_target.output = make_static_library_name( current_target.name );
break;
case target_build_type::SHARED_LIBRARY:
current_target.output = make_shared_library_name( current_target.name );
break;
}
auto sub_targets = conf[CONF_TARGET_LIST];
for ( const auto &target_conf : sub_targets ) {
bs::target new_target;
if ( append_sub_target( ctx, target_conf, new_target ) )
current_target.sub_targets.push_back( new_target );
}
return true;
}
return false;
}
static auto flags_to_compiler_options( bs::context &ctx, const std::vector<std::string> &flags ) {
std::vector<std::string> options;
for ( const auto &f : flags ) {
if ( f == CXX_FLAG_SUPPURT_CXX17 )
options.push_back( ctx.flags.support_cxx_17 );
if ( f == CXX_FLAG_ALL_WARNINGS )
options.push_back( ctx.flags.verbosity_warnings_all );
}
return options;
}
static auto process_default_debug_profile( bs::context &ctx ) {
}
static auto process_default_release_profile( bs::context &ctx ) {
}
static auto process_default_profile( bs::context &ctx, const std::string_view profile_name ) {
if ( profile_name == CONF_PROFILE_DEBUG ) {
ctx.cxx_compile_options.push_back( "-g" );
ctx.cxx_compile_options.push_back( "-O0" );
} else if ( profile_name == CONF_PROFILE_RELEASE ) {
ctx.cxx_compile_options.push_back( "-O3" );
} else {
/// Default profile
}
}
auto parse_conf( bs::context &ctx, std::string_view conf_path ) -> bool {
using namespace std;
error_code err;
if ( !fs::exists( conf_path, err ) ) {
return false;
}
auto start_time = bs::clock_type::now( );
auto conf = YAML::LoadFile( conf_path.data( ) );
const auto project_name = conf[CONF_PROJECT_NAME].as<string>( );
const auto profile_name = conf[CONF_PROFILE_TAG] ? conf[CONF_PROFILE_TAG].as<string>( ) : string{};
ctx.cxx_compiller = conf[CONF_CXX_COMPILLER] ? conf[CONF_CXX_COMPILLER].as<string>( ) : common::DEFAULT_CXX_COMPILER;
if ( conf[CONF_CXX_FLAGS].IsSequence( ) ) {
const auto global_cxx_flags = conf[CONF_CXX_FLAGS].as<vector<string>>( );
const auto global_cxx_options = flags_to_compiler_options( ctx, global_cxx_flags );
algorithm_utils::join_move( ctx.cxx_compile_options, global_cxx_options );
}
auto root_targets = conf[CONF_TARGET_LIST];
for ( const auto &target_conf : root_targets ) {
bs::target current_target;
if ( append_sub_target( ctx, target_conf, current_target ) ) {
ctx.build_targets.push_back( current_target );
}
}
if ( ctx.profile_name.empty( ) )
ctx.profile_name = profile_name;
process_default_profile( ctx, ctx.profile_name );
auto end_time = bs::clock_type::now( );
const chrono::duration<double> parse_time = end_time - start_time;
LOG_MESSAGE( APP_TAG, "[%2s] Parse '%1' done", conf_path, parse_time.count( ) );
return true;
}
} // namespace bs
} // namespace app