mirror of
https://github.com/reactos/ccache.git
synced 2025-01-07 11:30:34 +00:00
Add support for the -x GCC switch (Based on http://www.mail-archive.com/ccache@lists.samba.org/msg00399.html)
This commit is contained in:
parent
608c921cb0
commit
fbaca2f9de
169
ccache.c
169
ccache.c
@ -179,27 +179,44 @@ static int nlevels = 2;
|
||||
static int compile_preprocessed_source_code;
|
||||
|
||||
/* a list of supported file extensions, and the equivalent
|
||||
extension for code that has been through the pre-processor
|
||||
language
|
||||
*/
|
||||
static const struct {
|
||||
const char *extension;
|
||||
const char *i_extension;
|
||||
const char *language;
|
||||
} extensions[] = {
|
||||
{"c", "i"},
|
||||
{"C", "ii"},
|
||||
{"m", "mi"},
|
||||
{"cc", "ii"},
|
||||
{"CC", "ii"},
|
||||
{"cpp", "ii"},
|
||||
{"CPP", "ii"},
|
||||
{"cxx", "ii"},
|
||||
{"CXX", "ii"},
|
||||
{"c++", "ii"},
|
||||
{"C++", "ii"},
|
||||
{"i", "i"},
|
||||
{"ii", "ii"},
|
||||
{"i", "c-cpp-output"},
|
||||
{"ii", "c++-cpp-output"},
|
||||
{"mi", "objective-c-cpp-output"},
|
||||
{"mii", "objective-c++-cpp-output"},
|
||||
{"c", "c"},
|
||||
{"C", "c++"},
|
||||
{"m", "objective-c"},
|
||||
{"M", "objective-c++"},
|
||||
{"mm", "objective-c++"},
|
||||
{"cc", "c++"},
|
||||
{"CC", "c++"},
|
||||
{"cpp", "c++"},
|
||||
{"CPP", "c++"},
|
||||
{"cxx", "c++"},
|
||||
{"CXX", "c++"},
|
||||
{"c++", "c++"},
|
||||
{"C++", "c++"},
|
||||
{NULL, NULL}};
|
||||
|
||||
/* A list of languages and the equivalent language
|
||||
after it has been preprocessed.
|
||||
*/
|
||||
static const struct {
|
||||
const char *language;
|
||||
const char *preprocessed_language;
|
||||
} preprocessed_languages[] = {
|
||||
{"c", "c-cpp-output"},
|
||||
{"c++", "c++-cpp-output"},
|
||||
{"objective-c", "objective-c-cpp-output"},
|
||||
{"objective-c++", "objective-c++-cpp-output"},
|
||||
{NULL, NULL}};
|
||||
|
||||
enum fromcache_call_mode {
|
||||
FROMCACHE_DIRECT_MODE,
|
||||
FROMCACHE_CPP_MODE,
|
||||
@ -479,6 +496,62 @@ static int process_preprocessed_file(struct mdfour *hash, const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Try to guess the language of a file based on its extension.
|
||||
* Return NULL if the extension is unknown.
|
||||
*/
|
||||
static const char *language_for_file(const char *fname)
|
||||
{
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
p = strrchr(fname, '.');
|
||||
if (!p) return NULL;
|
||||
p++;
|
||||
for (i=0; extensions[i].extension; i++) {
|
||||
if (strcmp(p, extensions[i].extension) == 0) {
|
||||
return extensions[i].language;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* For a given language, return the language of the preprocessed file. */
|
||||
static const char *preprocessed_language(const char *language, int *direct_i)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (direct_i) {
|
||||
*direct_i = 0;
|
||||
}
|
||||
for (i=0; preprocessed_languages[i].language; i++) {
|
||||
if (strcmp(language, preprocessed_languages[i].language) == 0) {
|
||||
return preprocessed_languages[i].preprocessed_language;
|
||||
}
|
||||
if (strcmp(language, preprocessed_languages[i].preprocessed_language) == 0) {
|
||||
if (direct_i) {
|
||||
*direct_i = 1;
|
||||
}
|
||||
return preprocessed_languages[i].preprocessed_language;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the default file extension for a language */
|
||||
static const char *extension_for_language(const char *language)
|
||||
{
|
||||
int i;
|
||||
const char *extension = getenv("CCACHE_EXTENSION");
|
||||
if (extension) return extension;
|
||||
|
||||
for (i=0; extensions[i].extension; i++) {
|
||||
if (strcmp(language, extensions[i].language) == 0) {
|
||||
return extensions[i].extension;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* run the real compiler and put the result in cache */
|
||||
static void to_cache(ARGS *args)
|
||||
{
|
||||
@ -486,6 +559,7 @@ static void to_cache(ARGS *args)
|
||||
struct stat st;
|
||||
int status;
|
||||
int compress;
|
||||
int i;
|
||||
|
||||
x_asprintf(&tmp_stdout, "%s.tmp.stdout.%s", cached_obj, tmp_string());
|
||||
x_asprintf(&tmp_stderr, "%s.tmp.stderr.%s", cached_obj, tmp_string());
|
||||
@ -503,6 +577,20 @@ static void to_cache(ARGS *args)
|
||||
putenv("DEPENDENCIES_OUTPUT");
|
||||
|
||||
if (compile_preprocessed_source_code) {
|
||||
for (i=0; i<args->argc; i++) {
|
||||
if (strcmp(args->argv[i], "-x") == 0) {
|
||||
i++;
|
||||
if (i < args->argc) {
|
||||
char* language = args->argv[i];
|
||||
const char* prepr_language = preprocessed_language(language, NULL);
|
||||
if (prepr_language == NULL) {
|
||||
failed();
|
||||
}
|
||||
args->argv[i] = x_strdup(prepr_language);
|
||||
free(language);
|
||||
}
|
||||
}
|
||||
}
|
||||
args_add(args, i_tmpfile);
|
||||
} else {
|
||||
args_add(args, input_file);
|
||||
@ -1187,35 +1275,6 @@ static void find_compiler(int argc, char **argv)
|
||||
orig_args->argv[0] = compiler;
|
||||
}
|
||||
|
||||
|
||||
/* check a filename for C/C++ extension. Return the pre-processor
|
||||
extension */
|
||||
static const char *check_extension(const char *fname, int *direct_i)
|
||||
{
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
if (direct_i) {
|
||||
*direct_i = 0;
|
||||
}
|
||||
|
||||
p = strrchr(fname, '.');
|
||||
if (!p) return NULL;
|
||||
p++;
|
||||
for (i=0; extensions[i].extension; i++) {
|
||||
if (strcmp(p, extensions[i].extension) == 0) {
|
||||
if (direct_i && strcmp(p, extensions[i].i_extension) == 0) {
|
||||
*direct_i = 1;
|
||||
}
|
||||
p = getenv("CCACHE_EXTENSION");
|
||||
if (p) return p;
|
||||
return extensions[i].i_extension;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
process the compiler options to form the correct set of options
|
||||
for obtaining the preprocessor output
|
||||
@ -1227,6 +1286,8 @@ static void process_args(int argc, char **argv, ARGS **preprocessor_args,
|
||||
int found_c_opt = 0;
|
||||
int found_S_opt = 0;
|
||||
int found_arch_opt = 0;
|
||||
int found_x_opt = 0;
|
||||
const char *input_language = NULL;
|
||||
struct stat st;
|
||||
/* is the dependency makefile name overridden with -MF? */
|
||||
int dependency_filename_specified = 0;
|
||||
@ -1257,8 +1318,7 @@ static void process_args(int argc, char **argv, ARGS **preprocessor_args,
|
||||
strcmp(argv[i], "-fprofile-generate") == 0 ||
|
||||
strcmp(argv[i], "-fprofile-use") == 0 ||
|
||||
strcmp(argv[i], "-ftest-coverage") == 0 ||
|
||||
strcmp(argv[i], "-save-temps") == 0 ||
|
||||
strncmp(argv[i], "-x", 2) == 0) {
|
||||
strcmp(argv[i], "-save-temps") == 0) {
|
||||
cc_log("Compiler option %s is unsupported", argv[i]);
|
||||
stats_update(STATS_UNSUPPORTED);
|
||||
failed();
|
||||
@ -1300,6 +1360,12 @@ static void process_args(int argc, char **argv, ARGS **preprocessor_args,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -x can change the extension for the next input file */
|
||||
if ((strcmp(argv[i], "-x") == 0) && !input_file) {
|
||||
found_x_opt = 1;
|
||||
input_language = argv[i+1];
|
||||
}
|
||||
|
||||
/* we need to work out where the output was meant to go */
|
||||
if (strcmp(argv[i], "-o") == 0) {
|
||||
if (i == argc-1) {
|
||||
@ -1513,7 +1579,7 @@ static void process_args(int argc, char **argv, ARGS **preprocessor_args,
|
||||
}
|
||||
|
||||
if (input_file) {
|
||||
if (check_extension(argv[i], NULL)) {
|
||||
if (language_for_file(argv[i])) {
|
||||
cc_log("Multiple input files: %s and %s",
|
||||
input_file, argv[i]);
|
||||
stats_update(STATS_MULTIPLE);
|
||||
@ -1541,12 +1607,15 @@ static void process_args(int argc, char **argv, ARGS **preprocessor_args,
|
||||
failed();
|
||||
}
|
||||
|
||||
i_extension = check_extension(input_file, &direct_i_file);
|
||||
if (i_extension == NULL) {
|
||||
if ((input_language == NULL) || (strcmp(input_language, "none") == 0)) {
|
||||
input_language = language_for_file(input_file);
|
||||
}
|
||||
if (input_language == NULL) {
|
||||
cc_log("Not a C/C++ file: %s", input_file);
|
||||
stats_update(STATS_NOTC);
|
||||
failed();
|
||||
}
|
||||
}
|
||||
i_extension = extension_for_language(preprocessed_language(input_language, &direct_i_file));
|
||||
|
||||
if (!found_c_opt) {
|
||||
cc_log("No -c option found");
|
||||
|
Loading…
Reference in New Issue
Block a user