Commit aacc2cb8 authored by Kevin Locke's avatar Kevin Locke Committed by David Gibson

configurator: Add output cflag option and macro

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.aspxSigned-off-by: default avatarKevin Locke <kevin@kevinlocke.name>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent fcdcba92
...@@ -7,8 +7,12 @@ ...@@ -7,8 +7,12 @@
#ifndef CCAN_CFLAGS #ifndef CCAN_CFLAGS
#define CCAN_CFLAGS DEFAULT_CCAN_CFLAGS #define CCAN_CFLAGS DEFAULT_CCAN_CFLAGS
#endif #endif
#ifndef CCAN_OUTPUT_EXE_CFLAG
#define CCAN_OUTPUT_EXE_CFLAG DEFAULT_CCAN_OUTPUT_EXE_CFLAG
#endif
const char *compiler = CCAN_COMPILER; const char *compiler = CCAN_COMPILER;
const char *cflags = CCAN_CFLAGS; const char *cflags = CCAN_CFLAGS;
const char *outexecflag = CCAN_OUTPUT_EXE_CFLAG;
bool compile_verbose = false; bool compile_verbose = false;
...@@ -37,8 +41,9 @@ bool compile_object(const void *ctx, const char *cfile, const char *ccandir, ...@@ -37,8 +41,9 @@ bool compile_object(const void *ctx, const char *cfile, const char *ccandir,
if (compile_verbose) if (compile_verbose)
printf("Compiling %s\n", outfile); printf("Compiling %s\n", outfile);
return run_command(ctx, NULL, output, return run_command(ctx, NULL, output,
"%s %s -I%s -c -o %s %s", "%s %s -I%s -c %s%s %s",
compiler, cflags, ccandir, outfile, cfile); compiler, cflags, ccandir,
outexecflag, outfile, cfile);
} }
/* Compile and link single C file, with object files. /* 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, ...@@ -51,7 +56,7 @@ bool compile_and_link(const void *ctx, const char *cfile, const char *ccandir,
if (compile_verbose) if (compile_verbose)
printf("Compiling and linking %s\n", outfile); printf("Compiling and linking %s\n", outfile);
return run_command(ctx, NULL, output, return run_command(ctx, NULL, output,
"%s %s -I%s -o %s %s %s %s", "%s %s -I%s %s%s %s %s %s",
compiler, cflags, compiler, cflags, ccandir,
ccandir, outfile, cfile, objs, libs); outexecflag, outfile, cfile, objs, libs);
} }
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define DEFAULT_COMPILER "cc" #define DEFAULT_COMPILER "cc"
#define DEFAULT_FLAGS "-g3 -ggdb -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition" #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 OUTPUT_FILE "configurator.out"
#define INPUT_FILE "configuratortest.c" #define INPUT_FILE "configuratortest.c"
...@@ -465,10 +466,12 @@ static char *run(const char *cmd, int *exitstatus) ...@@ -465,10 +466,12 @@ static char *run(const char *cmd, int *exitstatus)
return ret; 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; char *ret;
size_t len = strlen(outflag) + strlen(files) + 1;
for (i = 1; argv[i]; i++) for (i = 1; argv[i]; i++)
len += 1 + strlen(argv[i]); len += 1 + strlen(argv[i]);
...@@ -478,10 +481,12 @@ static char *connect_args(const char *argv[], const char *extra) ...@@ -478,10 +481,12 @@ static char *connect_args(const char *argv[], const char *extra)
for (i = 1; argv[i]; i++) { for (i = 1; argv[i]; i++) {
strcpy(ret + len, argv[i]); strcpy(ret + len, argv[i]);
len += strlen(argv[i]); len += strlen(argv[i]);
if (argv[i+1]) if (argv[i+1] || *outflag)
ret[len++] = ' '; ret[len++] = ' ';
} }
strcpy(ret + len, extra); strcpy(ret + len, outflag);
len += strlen(outflag);
strcpy(ret + len, files);
return ret; return ret;
} }
...@@ -650,33 +655,47 @@ int main(int argc, const char *argv[]) ...@@ -650,33 +655,47 @@ int main(int argc, const char *argv[])
unsigned int i; unsigned int i;
const char *default_args[] const char *default_args[]
= { "", DEFAULT_COMPILER, DEFAULT_FLAGS, NULL }; = { "", DEFAULT_COMPILER, DEFAULT_FLAGS, NULL };
const char *outflag = DEFAULT_OUTPUT_EXE_FLAG;
if (argc > 0) if (argc > 0)
progname = argv[0]; progname = argv[0];
if (argc > 1) { while (argc > 1) {
if (strcmp(argv[1], "--help") == 0) { if (strcmp(argv[1], "--help") == 0) {
printf("Usage: configurator [-v] [<compiler> <flags>...]\n" printf("Usage: configurator [-v] [-O<outflag>] [<compiler> <flags>...]\n"
" <compiler> <flags> will have \"-o <outfile> <infile.c>\" appended\n" " <compiler> <flags> will have \"<outflag> <outfile> <infile.c>\" appended\n"
"Default: %s %s\n", "Default: %s %s %s\n",
DEFAULT_COMPILER, DEFAULT_FLAGS); DEFAULT_COMPILER, DEFAULT_FLAGS,
DEFAULT_OUTPUT_EXE_FLAG);
exit(0); exit(0);
} }
if (strcmp(argv[1], "-v") == 0) { if (strncmp(argv[1], "-O", 2) == 0) {
argc--;
argv++;
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--; argc--;
argv++; argv++;
verbose = 1; verbose++;
} else if (strcmp(argv[1], "-vv") == 0) { } else if (strcmp(argv[1], "-vv") == 0) {
argc--; argc--;
argv++; argv++;
verbose = 2; verbose += 2;
} else {
break;
} }
} }
if (argc == 1) if (argc == 1)
argv = default_args; 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++) for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
run_test(cmd, &tests[i]); run_test(cmd, &tests[i]);
free(cmd); free(cmd);
...@@ -691,9 +710,10 @@ int main(int argc, const char *argv[]) ...@@ -691,9 +710,10 @@ int main(int argc, const char *argv[])
printf("#define _GNU_SOURCE /* Always use GNU extensions. */\n"); printf("#define _GNU_SOURCE /* Always use GNU extensions. */\n");
printf("#endif\n"); printf("#endif\n");
printf("#define CCAN_COMPILER \"%s\"\n", argv[1]); printf("#define CCAN_COMPILER \"%s\"\n", argv[1]);
cmd = connect_args(argv+1, ""); cmd = connect_args(argv + 1, "", "");
printf("#define CCAN_CFLAGS \"%s\"\n\n", cmd); printf("#define CCAN_CFLAGS \"%s\"\n", cmd);
free(cmd); free(cmd);
printf("#define CCAN_OUTPUT_EXE_CFLAG \"%s\"\n\n", outflag);
/* This one implies "#include <ccan/..." works, eg. for tdb2.h */ /* This one implies "#include <ccan/..." works, eg. for tdb2.h */
printf("#define HAVE_CCAN 1\n"); printf("#define HAVE_CCAN 1\n");
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
/* These are the defaults. */ /* These are the defaults. */
#define DEFAULT_CCAN_COMPILER "cc" #define DEFAULT_CCAN_COMPILER "cc"
#define DEFAULT_CCAN_CFLAGS "-g" #define DEFAULT_CCAN_CFLAGS "-g"
#define DEFAULT_CCAN_OUTPUT_EXE_CFLAG "-o"
#define IDENT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ #define IDENT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \ "abcdefghijklmnopqrstuvwxyz" \
...@@ -20,8 +21,9 @@ ...@@ -20,8 +21,9 @@
#define COVERAGE_CFLAGS "-fprofile-arcs -ftest-coverage" #define COVERAGE_CFLAGS "-fprofile-arcs -ftest-coverage"
/* Actual compiler and cflags (defaults to CCAN_COMPILER and CCAN_CFLAGS). */ /* Actual compiler and cflags
extern const char *compiler, *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. */ /* This compiles up the _info file into a temporary. */
char *compile_info(const void *ctx, const char *dir); char *compile_info(const void *ctx, const char *dir);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment