From: Joel Rosdahl Date: Sat, 6 Feb 2016 16:05:24 +0000 (+0100) Subject: Recognize concatenated form of some long compiler options X-Git-Tag: v3.3~121 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dc1bd5f5d49950911223bce4b8192ea1042cf19;p=thirdparty%2Fccache.git Recognize concatenated form of some long compiler options --- diff --git a/NEWS.txt b/NEWS.txt index 28708a6ae..109084067 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -22,6 +22,9 @@ New features and improvements which specifies one or several prefixes to add to the command line ccache uses when invoking the preprocessor. +- The concatenated form of some long compiler options is now recognized, for + example when using `-isystemPATH` instead of `-isystem PATH`. + Bug fixes ~~~~~~~~~ diff --git a/ccache.c b/ccache.c index 0620a507c..d7eb87ef5 100644 --- a/ccache.c +++ b/ccache.c @@ -2512,7 +2512,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args, continue; } - /* Same as above but options with concatenated argument. */ + /* Same as above but short options with concatenated argument. */ if (compopt_short(compopt_takes_path, argv[i])) { char *relpath; char *option; @@ -2530,6 +2530,30 @@ cc_process_args(struct args *args, struct args **preprocessor_args, continue; } + /* Same as above but long options with concatenated argument beginning with + * a slash. */ + if (argv[i][0] == '-') { + char *slash_pos = strchr(argv[i], '/'); + if (slash_pos) { + char *option = x_strndup(argv[i], slash_pos - argv[i]); + if (compopt_affects_cpp(option)) { + if (compopt_takes_concat_arg(option)) { + char *relpath = make_relative_path(x_strdup(slash_pos)); + args_add(cpp_args, option); + args_add(cpp_args, relpath); + free(relpath); + } else { + args_add(cpp_args, argv[i]); + } + } else { + args_add(stripped_args, argv[i]); + } + + free(option); + continue; + } + } + /* options that take an argument */ if (compopt_takes_arg(argv[i])) { if (i == argc-1) { diff --git a/compopt.c b/compopt.c index 87166df4e..4516c5173 100644 --- a/compopt.c +++ b/compopt.c @@ -61,26 +61,27 @@ static const struct compopt compopts[] = { {"-fplugin=libcc1plugin", TOO_HARD}, /* interaction with GDB */ {"-frepo", TOO_HARD}, {"-fworking-directory", AFFECTS_CPP}, - {"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, + {"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-iframework", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, - {"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-imultilib", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-include", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-include-pch", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, + {"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-imultilib", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-include", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-include-pch", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-install_name", TAKES_ARG}, /* Darwin linker option */ - {"-iprefix", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-iquote", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-isysroot", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-isystem", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-iwithprefix", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, - {"-iwithprefixbefore", AFFECTS_CPP | TAKES_ARG | TAKES_PATH}, + {"-iprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-iquote", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-isysroot", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-isystem", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-iwithprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-iwithprefixbefore", + AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-nostdinc", AFFECTS_CPP}, {"-nostdinc++", AFFECTS_CPP}, {"-remap", AFFECTS_CPP}, {"-save-temps", TOO_HARD}, {"-stdlib=", AFFECTS_CPP | TAKES_CONCAT_ARG}, {"-trigraphs", AFFECTS_CPP}, - {"-u", TAKES_ARG}, + {"-u", TAKES_ARG | TAKES_CONCAT_ARG}, }; @@ -182,6 +183,13 @@ compopt_takes_arg(const char *option) return co && (co->type & TAKES_ARG); } +bool +compopt_takes_concat_arg(const char *option) +{ + const struct compopt *co = find(option); + return co && (co->type & TAKES_CONCAT_ARG); +} + /* Determines if the prefix of the option matches any option and affects the * preprocessor. */ diff --git a/compopt.h b/compopt.h index 882187dbc..109094b66 100644 --- a/compopt.h +++ b/compopt.h @@ -9,6 +9,7 @@ bool compopt_too_hard(const char *option); bool compopt_too_hard_for_direct_mode(const char *option); bool compopt_takes_path(const char *option); bool compopt_takes_arg(const char *option); +bool compopt_takes_concat_arg(const char *option); bool compopt_prefix_affects_cpp(const char *option); #endif /* CCACHE_COMPOPT_H */ diff --git a/test/test_argument_processing.c b/test/test_argument_processing.c index 0ecefd1b3..20ae65a07 100644 --- a/test/test_argument_processing.c +++ b/test/test_argument_processing.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 Joel Rosdahl + * Copyright (C) 2010-2016 Joel Rosdahl * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -297,4 +297,49 @@ TEST(fprofile_flag_with_nonexisting_dir_should_not_be_rewritten) args_free(orig); } +TEST(isystem_flag_with_separate_arg_should_be_rewritten_if_basedir_is_used) +{ + extern char *current_working_dir; + char *arg_string; + struct args *orig; + struct args *act_cpp = NULL, *act_cc = NULL; + + create_file("foo.c", ""); + free(conf->base_dir); + conf->base_dir = x_strdup("/"); + current_working_dir = get_cwd(); + arg_string = format("cc -isystem %s/foo -c foo.c", current_working_dir); + orig = args_init_from_string(arg_string); + + CHECK(cc_process_args(orig, &act_cpp, &act_cc)); + CHECK_STR_EQ("./foo", act_cpp->argv[2]); + + args_free(orig); + args_free(act_cpp); + args_free(act_cc); +} + +TEST(isystem_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used) +{ + extern char *current_working_dir; + char *arg_string; + struct args *orig; + struct args *act_cpp = NULL, *act_cc = NULL; + + create_file("foo.c", ""); + free(conf->base_dir); + conf->base_dir = x_strdup("/"); + current_working_dir = get_cwd(); + arg_string = format("cc -isystem%s/foo -c foo.c", current_working_dir); + orig = args_init_from_string(arg_string); + + CHECK(cc_process_args(orig, &act_cpp, &act_cc)); + CHECK_STR_EQ("-isystem", act_cpp->argv[1]); + CHECK_STR_EQ("./foo", act_cpp->argv[2]); + + args_free(orig); + args_free(act_cpp); + args_free(act_cc); +} + TEST_SUITE_END