-
-
Notifications
You must be signed in to change notification settings - Fork 79
/
gcc.cc
89 lines (82 loc) · 2.56 KB
/
gcc.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
// std
#include <cctype> // std::isdigit
// internal
#include "poac/core/builder/compiler/cxx/gcc.hpp"
#include "poac/core/builder/compiler/error.hpp"
#include "poac/util/shell.hpp"
namespace poac::core::builder::compiler::cxx::gcc {
[[nodiscard]] Fn get_compiler_version_impl(const String& cmd_output)
->Result<semver::Version> {
// `g++ (GCC) 11.2.0\n`
usize itr = cmd_output.find('(');
if (itr == None) {
return Err<error::FailedToGetCompilerVersion>(COMPILER);
}
itr = cmd_output.find(')', itr + 1);
String version;
for (itr += 2; itr < cmd_output.size(); ++itr) {
if (std::isdigit(cmd_output[itr]) || cmd_output[itr] == '.') {
version += cmd_output[itr];
} else {
break;
}
}
return Ok(semver::parse(version));
}
[[nodiscard]] Fn get_compiler_version(const String& compiler_command)
->Result<semver::Version> {
Let res = util::shell::Cmd(compiler_command + " --version").exec();
if (res.is_ok()) {
return get_compiler_version_impl(res.output());
}
return Err<error::FailedToGetCompilerVersion>(COMPILER);
}
// thanks to:
// https://gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/Compiler/GNU-CXX.cmake
[[nodiscard]] Fn get_std_flag(
const String& compiler_command, const i64 edition,
const bool use_gnu_extension
)
->Result<String> {
const semver::Version version = Try(get_compiler_version(compiler_command));
const String specifier = use_gnu_extension ? "gnu" : "c";
switch (edition) {
case 1998:
if (version >= "3.4.0") {
return Ok(format("-std={}++98", specifier));
}
break;
case 2011:
if (version >= "4.7.0") {
return Ok(format("-std={}++11", specifier));
} else if (version >= "4.4.0") {
return Ok(format("-std={}++0x", specifier));
}
break;
case 2014:
if (version >= "4.9.0") {
return Ok(format("-std={}++14", specifier));
} else if (version >= "4.8.0") {
return Ok(format("-std={}++1y", specifier));
}
break;
case 2017:
if (version >= "8.0.0") {
return Ok(format("-std={}++17", specifier));
} else if (version >= "5.1.0") {
return Ok(format("-std={}++1z", specifier));
}
break;
case 2020:
if (version >= "11.1.0") {
return Ok(format("-std={}++20", specifier));
} else if (version >= "8.0.0") {
return Ok(format("-std={}++2a", specifier));
}
break;
}
return Err<error::UnsupportedLangVersion>(
COMPILER, version, lang::Lang::cxx, edition
);
}
} // namespace poac::core::builder::compiler::cxx::gcc