Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Tricore compiler from Tasking #942

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ parse_compiler_type(const std::string& value)
return CompilerType::nvcc;
} else if (value == "other") {
return CompilerType::other;
} else if (value == "cctc") {
return CompilerType::cctc;
} else if (value == "ctc") {
return CompilerType::ctc;
} else {
// Allow any unknown value for forward compatibility.
return CompilerType::auto_guess;
Expand Down Expand Up @@ -480,6 +484,8 @@ compiler_type_to_string(CompilerType compiler_type)
CASE(msvc);
CASE(nvcc);
CASE(other);
CASE(ctc);
CASE(cctc);
}
#undef CASE

Expand Down
4 changes: 3 additions & 1 deletion src/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ enum class CompilerType {
icl,
msvc,
nvcc,
other
other,
ctc,
cctc
};

std::string compiler_type_to_string(CompilerType compiler_type);
Expand Down
78 changes: 74 additions & 4 deletions src/Depfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,26 +146,78 @@ tokenize(std::string_view file_content)
{
// A dependency file uses Makefile syntax. This is not perfect parser but
// should be enough for parsing a regular dependency file.
// enhancement:
// - space between target and colon
// - no space between colon and first pre-requisite
// the later is pretty complex because of the windows paths which are
// identical to a target-colon-prerequisite without spaces (e.g. cat:/meow vs.
// c:/meow) here are the tests on windows gnu make 4.3 how it handles this:
// + cat:/meow -> sees "cat" and "/meow"
// + cat:\meow -> sees "cat" and "\meow"
// + cat:\ meow -> sees "cat" and " meow"
// + cat:c:/meow -> sees "cat" and "c:/meow"
// + cat:c:\meow -> sees "cat" and "c:\meow"
// + cat:c: -> target pattern contains no '%'. Stop.
// + cat:c:\ -> target pattern contains no '%'. Stop.
// + cat:c:/ -> sees "cat" and "c:/"
// + cat:c:meow -> target pattern contains no '%'. Stop.
// + c:c:/meow -> sees "c" and "c:/meow"
// + c:c:\meow -> sees "c" and "c:\meow"
// + c:z:\meow -> sees "c" and "z:\meow"
// + c:cd:\meow -> target pattern contains no '%'. Stop.

// the logic for a windows path is:
// - if there is a colon, if the previous token is 1 char long
// and that the following char is a slash (fw or bw), then it is
// a windows path

std::vector<std::string> result;
const size_t length = file_content.size();
std::string token;
size_t p = 0;

while (p < length) {
// Each token is separated by whitespace.
if (isspace(file_content[p])) {
char c = file_content[p];

if (c == ':') {
if (p + 1 < length && !is_blank(token) && token.length() == 1) {
const char next = file_content[p + 1];
if (next == '/' || next == '\\') {
// only in this case, this is not a separator and colon is
// added to token
token.push_back(c);
++p;
continue;
}
}
}
// Each token is separated by whitespace or a colon.
if (isspace(c) || c == ':') {
// chomp all spaces before next char
while (p < length && isspace(file_content[p])) {
++p;
}
if (!is_blank(token)) {
// if there were spaces between a token and the : sign, the :
// must be added to the same token to make sure it is seen as
// a target and not as a dependency (ccache requirement)
if (p < length) {
const char next = file_content[p];
if (next == ':') {
token.push_back(next);
++p;
// chomp all spaces before next char
while (p < length && isspace(file_content[p])) {
++p;
}
}
}
result.push_back(token);
}
token.clear();
continue;
}

char c = file_content[p];
switch (c) {
case '\\':
if (p + 1 < length) {
Expand All @@ -182,7 +234,7 @@ tokenize(std::string_view file_content)
++p;
break;
// Backslash followed by newline is interpreted like a space, so simply
// the backslash.
// discard the backslash.
case '\n':
++p;
continue;
Expand All @@ -199,6 +251,24 @@ tokenize(std::string_view file_content)
}
}
break;
// this is specific to TASKING compiler: filenames are quoted (not
// supported by gnu make)
case '"':
// quotes should take everything until next quotes
// skip the first quote
++p;
while (p < length) {
const char next = file_content[p];
if (next == '"') {
// skip the last quote
++p;
break;
} else {
token.push_back(next);
++p;
}
}
continue;
}

token.push_back(c);
Expand Down
112 changes: 92 additions & 20 deletions src/argprocessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,16 @@ process_option_arg(const Context& ctx,
return Statistic::called_for_preprocessing;
}

if (config.compiler_type() == CompilerType::cctc
|| config.compiler_type() == CompilerType::ctc) {
// tasking specific common to compiler and control
if (args[i] == "-n" || args[i] == "--stdout") {
// dry run or stdout
args_info.output_obj = "-";
return Statistic::none;
}
}

// Handle "@file" argument.
if (util::starts_with(args[i], "@") || util::starts_with(args[i], "-@")) {
const char* argpath = args[i].c_str() + 1;
Expand All @@ -333,17 +343,28 @@ process_option_arg(const Context& ctx,
return Statistic::none;
}

// Handle cuda "-optf" and "--options-file" argument.
if (config.compiler_type() == CompilerType::nvcc
&& (args[i] == "-optf" || args[i] == "--options-file")) {
if (i == args.size() - 1) {
LOG("Expected argument after {}", args[i]);
return Statistic::bad_compiler_arguments;
// Handle cuda "-optf" and "--options-file" argument and tasking "-f" and
// "--option-file" argument.
if ((config.compiler_type() == CompilerType::nvcc
&& (args[i] == "-optf" || args[i] == "--options-file"))
|| ((config.compiler_type() == CompilerType::cctc
|| config.compiler_type() == CompilerType::ctc)
&& (args[i] == "-f"
|| util::starts_with(args[i], "--option-file=")))) {
Comment on lines +348 to +353

Check notice

Code scanning / CodeQL

Complex condition

Complex condition: too many logical operations in this expression.
std::string_view optionfiles;
if (util::starts_with(args[i], "--option-file=")) {
optionfiles = std::string_view(args[i]).substr(14);
} else {
if (i == args.size() - 1) {
LOG("Expected argument after {}", args[i]);
return Statistic::bad_compiler_arguments;
}
++i;
optionfiles = std::string_view(args[i]);
}
++i;

// Argument is a comma-separated list of files.
auto paths = Util::split_into_strings(args[i], ",");
auto paths = Util::split_into_strings(optionfiles, ",");
for (auto it = paths.rbegin(); it != paths.rend(); ++it) {
auto file_args = Args::from_atfile(*it);
if (!file_args) {
Expand Down Expand Up @@ -477,7 +498,14 @@ process_option_arg(const Context& ctx,
}

// We must have -c.
if (args[i] == "-c") {
if (args[i] == "-c" && config.compiler_type() != CompilerType::ctc) {
state.found_c_opt = true;
return Statistic::none;
}

if (config.compiler_type() == CompilerType::cctc
&& (args[i] == "-co" || args[i] == "-cobject" || args[i] == "--create=o"
|| args[i] == "--create=object")) {
state.found_c_opt = true;
return Statistic::none;
}
Expand Down Expand Up @@ -555,6 +583,15 @@ process_option_arg(const Context& ctx,
return Statistic::none;
}

// Alternate form of -o for Tasking.
if (util::starts_with(args[i], "--output=")
&& (config.compiler_type() == CompilerType::ctc
|| config.compiler_type() == CompilerType::cctc)) {
args_info.output_obj =
Util::make_relative_path(ctx, std::string_view(args[i]).substr(9));
return Statistic::none;
}

if (util::starts_with(args[i], "-fdebug-prefix-map=")
|| util::starts_with(args[i], "-ffile-prefix-map=")) {
std::string map = args[i].substr(args[i].find('=') + 1);
Expand All @@ -565,7 +602,10 @@ process_option_arg(const Context& ctx,

// Debugging is handled specially, so that we know if we can strip line
// number info.
if (util::starts_with(args[i], "-g")) {
if (util::starts_with(args[i], "-g")
|| (util::starts_with(args[i], "--debug-info")
&& (config.compiler_type() == CompilerType::ctc
|| config.compiler_type() == CompilerType::cctc))) {
state.common_args.push_back(args[i]);

if (util::starts_with(args[i], "-gdwarf")) {
Expand Down Expand Up @@ -599,17 +639,26 @@ process_option_arg(const Context& ctx,

// These options require special handling, because they behave differently
// with gcc -E, when the output file is not specified.
if ((args[i] == "-MD" || args[i] == "-MMD")
if ((args[i] == "-MD" || args[i] == "-MMD" || args[i] == "--dep-file")
&& !config.is_compiler_group_msvc()) {
state.found_md_or_mmd_opt = true;
args_info.generating_dependencies = true;
state.dep_args.push_back(args[i]);
return Statistic::none;
}

if (util::starts_with(args[i], "-MF")) {
if (util::starts_with(args[i], "-MF")
|| util::starts_with(args[i], "--dep-file=")) {
state.found_mf_opt = true;

if (config.compiler_type() == CompilerType::ctc
|| config.compiler_type() == CompilerType::cctc) {
// with tasking compiler, the dep-file option also enables the
// generation of the dependencies
state.found_md_or_mmd_opt = true;
args_info.generating_dependencies = true;
}

std::string dep_file;
bool separate_argument = (args[i].size() == 3);
if (separate_argument) {
Expand All @@ -621,8 +670,13 @@ process_option_arg(const Context& ctx,
dep_file = args[i + 1];
i++;
} else {
// -MFarg or -MF=arg (EDG-based compilers)
dep_file = args[i].substr(args[i][3] == '=' ? 4 : 3);
// -MFarg or -MF=arg (EDG-based compilers) or --dep-file=arg
size_t equal_pos = args[i].find('=');
if (equal_pos == std::string::npos) {
dep_file = args[i].substr(3);
} else {
dep_file = args[i].substr(equal_pos + 1);
}
}

if (state.output_dep_origin <= OutputDepOrigin::mf) {
Expand All @@ -634,7 +688,11 @@ process_option_arg(const Context& ctx,
state.dep_args.push_back("-MF");
state.dep_args.push_back(args_info.output_dep);
} else {
state.dep_args.push_back("-MF" + args_info.output_dep);
if (util::starts_with(args[i], "--dep-file=")) {
state.dep_args.push_back("--dep-file=" + args_info.output_dep);
} else {
state.dep_args.push_back("-MF" + args_info.output_dep);
}
}
return Statistic::none;
}
Expand Down Expand Up @@ -1099,6 +1157,11 @@ process_arg(const Context& ctx,
}
}

// ctc can only generate object files
if (config.compiler_type() == CompilerType::ctc) {
state.found_c_opt = true;
}

// Rewrite to relative to increase hit rate.
args_info.orig_input_file = args[i];
args_info.input_file = Util::make_relative_path(ctx, args[i]);
Expand Down Expand Up @@ -1181,10 +1244,19 @@ process_args(Context& ctx)
}

if (output_obj_by_source && !args_info.input_file.empty()) {
std::string_view extension =
state.found_S_opt ? ".s" : get_default_object_file_extension(ctx.config);
args_info.output_obj +=
Util::change_extension(Util::base_name(args_info.input_file), extension);
if (config.compiler_type() == CompilerType::ctc) {
args_info.output_obj =
Util::change_extension(Util::base_name(args_info.input_file), ".src");
} else if (config.compiler_type() == CompilerType::ctc) {
args_info.output_obj =
Util::change_extension(Util::base_name(args_info.input_file), ".elf");
} else {
std::string_view extension =
state.found_S_opt ? ".s"
: get_default_object_file_extension(ctx.config);
args_info.output_obj += Util::change_extension(
Util::base_name(args_info.input_file), extension);
}
}

args_info.orig_output_obj = args_info.output_obj;
Expand Down Expand Up @@ -1433,7 +1505,7 @@ process_args(Context& ctx)
compiler_args.push_back(p_language_for_language(state.explicit_language));
}

if (state.found_c_opt) {
if (state.found_c_opt && config.compiler_type() != CompilerType::ctc) {
compiler_args.push_back("-c");
}

Expand Down
16 changes: 15 additions & 1 deletion src/ccache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ guess_compiler(std::string_view path)
return CompilerType::icl;
} else if (name == "cl") {
return CompilerType::msvc;
} else if (name.find("cctc") != std::string_view::npos) {
return CompilerType::cctc;
} else if (name.find("ctc") != std::string_view::npos) {
return CompilerType::ctc;
} else {
return CompilerType::other;
}
Expand Down Expand Up @@ -642,7 +646,15 @@ result_key_from_depfile(Context& ctx, Hash& hash)
if (util::ends_with(token, ":")) {
continue;
}

std::string path = Util::make_relative_path(ctx, token);

if (ctx.config.compiler_type() == CompilerType::cctc
|| ctx.config.compiler_type() == CompilerType::ctc) {
// tasking requires to normalize the paths from the depend file
path = Util::normalize_concrete_absolute_path(path);
}

remember_include_file(ctx, path, hash, false, &hash);
}

Expand Down Expand Up @@ -2148,6 +2160,7 @@ cache_compilation(int argc, const char* const* argv)
Args saved_orig_args;
std::optional<uint32_t> original_umask;
std::string saved_temp_dir;
CompilerType compiler_type;

{
Context ctx;
Expand All @@ -2164,6 +2177,7 @@ cache_compilation(int argc, const char* const* argv)
const auto result = do_cache_compilation(ctx, argv);
const auto& counters = result ? *result : result.error().counters();
ctx.storage.local.increment_statistics(counters);
compiler_type = ctx.config.compiler_type();
if (!result) {
if (result.error().exit_code()) {
return *result.error().exit_code();
Expand Down Expand Up @@ -2194,7 +2208,7 @@ cache_compilation(int argc, const char* const* argv)
Util::set_umask(*original_umask);
}
auto execv_argv = saved_orig_args.to_argv();
execute_noreturn(execv_argv.data(), saved_temp_dir);
execute_noreturn(execv_argv.data(), saved_temp_dir, compiler_type);
throw core::Fatal(
FMT("execute_noreturn of {} failed: {}", execv_argv[0], strerror(errno)));
}
Expand Down