On Thu, Sep 22, 2016 at 09:33:11PM -0600, Kevin Locke wrote:
> 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>

Reviewed-by: David Gibson <da...@gibson.dropbear.id.au>

This one has some more complex conflicts if applied without the
preceding ones, so I haven't applied it yet.

> ---
>  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 acf6cc0..d81f878 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"
> @@ -517,10 +518,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]);
> @@ -530,10 +533,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;
>  }
>  
> @@ -702,33 +707,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);
> @@ -743,9 +762,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);

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature

_______________________________________________
ccan mailing list
ccan@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/ccan

Reply via email to