Unfortunately, not all compilers support -o as a command-line option for specifying the output file. Visual Studio cl.exe issues warning D9035 when -o is given, which is detected as a compile warning by the configurator.
To support such compilers, add the command-line option -O to configurator which can be used to specify the cflag for setting the output executable file name. Additionally define the macro CCAN_OUTPUT_EXE_CFLAG in config.h and use it when invoking the compiler (e.g. from ccanlint). For reference, the name CCAN_OUTPUT_EXE_CFLAG was chosen to avoid potential name conflicts in the future due to cl.exe requiring different flags for different types of output[1] (e.g. object files are /Fo:). 1. https://msdn.microsoft.com/en-us/library/f1cb223a.aspx Signed-off-by: Kevin Locke <ke...@kevinlocke.name> --- tools/compile.c | 15 ++++++++---- tools/configurator/configurator.c | 50 +++++++++++++++++++++++++++------------ tools/tools.h | 6 +++-- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/tools/compile.c b/tools/compile.c index b88c1d8..e796e3f 100644 --- a/tools/compile.c +++ b/tools/compile.c @@ -7,8 +7,12 @@ #ifndef CCAN_CFLAGS #define CCAN_CFLAGS DEFAULT_CCAN_CFLAGS #endif +#ifndef CCAN_OUTPUT_EXE_CFLAG +#define CCAN_OUTPUT_EXE_CFLAG DEFAULT_CCAN_OUTPUT_EXE_CFLAG +#endif const char *compiler = CCAN_COMPILER; const char *cflags = CCAN_CFLAGS; +const char *outexecflag = CCAN_OUTPUT_EXE_CFLAG; bool compile_verbose = false; @@ -37,8 +41,9 @@ bool compile_object(const void *ctx, const char *cfile, const char *ccandir, if (compile_verbose) printf("Compiling %s\n", outfile); return run_command(ctx, NULL, output, - "%s %s -I%s -c -o %s %s", - compiler, cflags, ccandir, outfile, cfile); + "%s %s -I%s -c %s%s %s", + compiler, cflags, ccandir, + outexecflag, outfile, cfile); } /* Compile and link single C file, with object files. @@ -51,7 +56,7 @@ bool compile_and_link(const void *ctx, const char *cfile, const char *ccandir, if (compile_verbose) printf("Compiling and linking %s\n", outfile); return run_command(ctx, NULL, output, - "%s %s -I%s -o %s %s %s %s", - compiler, cflags, - ccandir, outfile, cfile, objs, libs); + "%s %s -I%s %s%s %s %s %s", + compiler, cflags, ccandir, + outexecflag, outfile, cfile, objs, libs); } diff --git a/tools/configurator/configurator.c b/tools/configurator/configurator.c index 73fdc95..4cb84d0 100644 --- a/tools/configurator/configurator.c +++ b/tools/configurator/configurator.c @@ -40,6 +40,7 @@ #define DEFAULT_COMPILER "cc" #define DEFAULT_FLAGS "-g3 -ggdb -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition" +#define DEFAULT_OUTPUT_EXE_FLAG "-o" #define OUTPUT_FILE "configurator.out" #define INPUT_FILE "configuratortest.c" @@ -465,10 +466,12 @@ static char *run(const char *cmd, int *exitstatus) return ret; } -static char *connect_args(const char *argv[], const char *extra) +static char *connect_args(const char *argv[], const char *outflag, + const char *files) { - unsigned int i, len = strlen(extra) + 1; + unsigned int i; char *ret; + size_t len = strlen(outflag) + strlen(files) + 1; for (i = 1; argv[i]; i++) len += 1 + strlen(argv[i]); @@ -478,10 +481,12 @@ static char *connect_args(const char *argv[], const char *extra) for (i = 1; argv[i]; i++) { strcpy(ret + len, argv[i]); len += strlen(argv[i]); - if (argv[i+1]) + if (argv[i+1] || *outflag) ret[len++] = ' '; } - strcpy(ret + len, extra); + strcpy(ret + len, outflag); + len += strlen(outflag); + strcpy(ret + len, files); return ret; } @@ -650,33 +655,47 @@ int main(int argc, const char *argv[]) unsigned int i; const char *default_args[] = { "", DEFAULT_COMPILER, DEFAULT_FLAGS, NULL }; + const char *outflag = DEFAULT_OUTPUT_EXE_FLAG; if (argc > 0) progname = argv[0]; - if (argc > 1) { + while (argc > 1) { if (strcmp(argv[1], "--help") == 0) { - printf("Usage: configurator [-v] [<compiler> <flags>...]\n" - " <compiler> <flags> will have \"-o <outfile> <infile.c>\" appended\n" - "Default: %s %s\n", - DEFAULT_COMPILER, DEFAULT_FLAGS); + printf("Usage: configurator [-v] [-O<outflag>] [<compiler> <flags>...]\n" + " <compiler> <flags> will have \"<outflag> <outfile> <infile.c>\" appended\n" + "Default: %s %s %s\n", + DEFAULT_COMPILER, DEFAULT_FLAGS, + DEFAULT_OUTPUT_EXE_FLAG); exit(0); } - if (strcmp(argv[1], "-v") == 0) { + if (strncmp(argv[1], "-O", 2) == 0) { argc--; argv++; - verbose = 1; + outflag = argv[1] + 2; + if (!*outflag) { + fprintf(stderr, + "%s: option requires an argument -- O\n", + argv[0]); + exit(1); + } + } else if (strcmp(argv[1], "-v") == 0) { + argc--; + argv++; + verbose++; } else if (strcmp(argv[1], "-vv") == 0) { argc--; argv++; - verbose = 2; + verbose += 2; + } else { + break; } } if (argc == 1) argv = default_args; - cmd = connect_args(argv, " -o " OUTPUT_FILE " " INPUT_FILE); + cmd = connect_args(argv, outflag, OUTPUT_FILE " " INPUT_FILE); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) run_test(cmd, &tests[i]); free(cmd); @@ -691,9 +710,10 @@ int main(int argc, const char *argv[]) printf("#define _GNU_SOURCE /* Always use GNU extensions. */\n"); printf("#endif\n"); printf("#define CCAN_COMPILER \"%s\"\n", argv[1]); - cmd = connect_args(argv+1, ""); - printf("#define CCAN_CFLAGS \"%s\"\n\n", cmd); + cmd = connect_args(argv + 1, "", ""); + printf("#define CCAN_CFLAGS \"%s\"\n", cmd); free(cmd); + printf("#define CCAN_OUTPUT_EXE_CFLAG \"%s\"\n\n", outflag); /* This one implies "#include <ccan/..." works, eg. for tdb2.h */ printf("#define HAVE_CCAN 1\n"); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) diff --git a/tools/tools.h b/tools/tools.h index 3b5c4be..668c91a 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -11,6 +11,7 @@ /* These are the defaults. */ #define DEFAULT_CCAN_COMPILER "cc" #define DEFAULT_CCAN_CFLAGS "-g" +#define DEFAULT_CCAN_OUTPUT_EXE_CFLAG "-o" #define IDENT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "abcdefghijklmnopqrstuvwxyz" \ @@ -20,8 +21,9 @@ #define COVERAGE_CFLAGS "-fprofile-arcs -ftest-coverage" -/* Actual compiler and cflags (defaults to CCAN_COMPILER and CCAN_CFLAGS). */ -extern const char *compiler, *cflags; +/* Actual compiler and cflags + * (defaults to CCAN_COMPILER, CCAN_CFLAGS, CCAN_OUTPUT_EXE_CFLAG). */ +extern const char *compiler, *cflags, *outexecflag; /* This compiles up the _info file into a temporary. */ char *compile_info(const void *ctx, const char *dir); -- 2.9.3 _______________________________________________ ccan mailing list ccan@lists.ozlabs.org https://lists.ozlabs.org/listinfo/ccan