coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] build: Option for building all tools in a single binary


From: Pádraig Brady
Subject: Re: [PATCH v2] build: Option for building all tools in a single binary
Date: Mon, 16 Jun 2014 10:36:35 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

On 06/16/2014 08:02 AM, Alex Deymo wrote:
> Hi again,
> 
> 1. If I set main with noreturn:
> int main (int argc, char **argv) ATTRIBUTE_NORETURN;
> 
> ...then I get this error, presumably because of the implicit "return 0" on 
> main... So I opted for adding ATTRIBUTE_NORETURN only when the main function 
> is renamed:
> <built-in>:0:0: error: function declared 'noreturn' has a 'return' statement 
> [-Werror]

Yes there are probably special cases for main().
Adding that at the define at the top of coreutils.c
like I suggested is fine.

> 2. Added --enable-single-binary-exceptions=prog1,prog2,... to handle this. It 
> build those as separated binaries. make install works without changes (since 
> the flag changes the variables at configure time).

Perfect.

> 3. Still no clue what's supposed to happen in that test with env, and can't 
> reproduce any difference between the single-binary and the normal mode 
> outside the test.

tests/misc/env.sh

> 4. "make" and "make check" problem
> The all-am target depends on the manpages $(MANS), which has all the 
> man/$prog.1 files. Those man/$prog.1 files depend on the src/$prog, which 
> should not be build in the single-binary case. Because of this dependency, 
> both src/coreutils and all the src/$prog are built. I added a PHONY target 
> after all-am that creates the symlinks on src/, but that doesn't work the 
> first time because makefile will evaluate the dependencies before we create 
> the symlinks, and it will use the rule it knows to generate the src/$prog 
> file (overriding the symlink).
> Ideas on how to solve this?

Maybe the dependency list could be generated and then included,
or perhaps use a dynamic depedency like.

  man/timeout.1:   $(get_binary_name $@)

I've not tried or used such a thing but a quick search suggests
it might work.


> diff --git a/src/coreutils.c b/src/coreutils.c

> +int
> +main (int argc, char **argv)
> +{
> +  static struct option const long_options[] =
> +  {
> +    {GETOPT_HELP_OPTION_DECL},
> +    {GETOPT_VERSION_OPTION_DECL},
> +    {NULL, 0, NULL, 0}
> +  };
> +
> +  char *prog_name = last_component (argv[0]);
> +  int prog_argc = argc;
> +  char **prog_argv = argv;
> +
> +  int opt;
> +
> +  /* If this program is called directly as "coreutils" instead of using a
> +   * symlink, we use argv[1] as the name of the program, shifting all the
> +   * arguments one position. */
> +  if (STREQ (prog_name, "coreutils"))
> +  {
> +    prog_argv++;
> +    prog_argc--;
> +    prog_name = prog_argv[0]; /* Don't use last_component() in this case. */
> +  }
> +
> +  /* Ensure that at least a parameter was passed to coreutils. */
> +  if (prog_argc < 1 || !prog_argv[0])
> +  {
> +    initialize_main (&argc, &argv);
> +    set_program_name (argv[0]);
> +    setlocale (LC_ALL, "");
> +    bindtextdomain (PACKAGE, LOCALEDIR);
> +    textdomain (PACKAGE);
> +    atexit (close_stdout);
> +
> +    usage (EXIT_FAILURE);
> +  }

Rather than repeating the above block it would be better
to adjust the following conditional to just skip
the _single_binary_...() call in that case and fall
through to internal handling then.

> +
> +  /* Lookup the right main program */
> +#define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) \
> +  if (STREQ (prog_name_str, prog_name)) \
> +    _single_binary_main_##main_name (prog_argc, prog_argv);
> +#include "coreutils.h"
> +#undef SINGLE_BINARY_PROGRAM
> +
> +  /* No known program was selected. From here on, we behave like any other
> +   * coreutils program. Handle the flags passed to this program. */
> +
> +  initialize_main (&argc, &argv);
> +  set_program_name (argv[0]);
> +  setlocale (LC_ALL, "");
> +  bindtextdomain (PACKAGE, LOCALEDIR);
> +  textdomain (PACKAGE);
> +  atexit (close_stdout);
> +
> +  if ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1)
> +  {
> +    switch (opt)
> +    {
> +      case_GETOPT_HELP_CHAR;
> +
> +      case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
> +
> +      default:
> +        usage (EXIT_FAILURE);
> +    }
> +  }
> +
> +  printf ("%s: program not found.\n", prog_name);
> +  usage (EXIT_FAILURE);
> +}


> diff --git a/src/kill.c b/src/kill.c

Your editor stripped out form feeds from this file at least. Please reinstate.


> diff --git a/src/local.mk b/src/local.mk

> +# Special case for programs that have multiple sources sharing global
> +# initialized variables between the sources, and that the sources are shared
> +# among more than one binary. These extra rules rename those global variables
> +# such that the name from one program doesn't conflict the variable on the
> +# other program.
> +# Programs with global variables private to a .c are not a problem since the
> +# references are resolved locally on each .c file.
> +src_libsinglebin_arch_a_CFLAGS += -Duname_mode=libsinglebin_arch_uname_mode
> +src_libsinglebin_uname_a_CFLAGS += -Duname_mode=libsinglebin_uname_uname_mode
> +
> +src_libsinglebin_ls_a_CFLAGS += -Dls_mode=libsinglebin_ls_ls_mode
> +src_libsinglebin_dir_a_CFLAGS += -Dls_mode=libsinglebin_dir_ls_mode
> +src_libsinglebin_vdir_a_CFLAGS += -Dls_mode=libsinglebin_vdir_ls_mode

Rather than having separate ..._main() functions for the above,
would it be possible to add special cases in coreutils.c to:

if (STREQ (prog, "ls"))
  {
    ls_mode = LS_LS;
  }
else if (STREQ (prog, "dir"))
  {
    ls_mode = LS_DIR;
    prog = "ls";
  }

This should share more code right?
Actually the above defines don't seem right as I just got this:

$ ./configure --enable-single-binary --enable-single-binary-exceptions=sort && 
make
src/libsinglebin_dir.a(src_libsinglebin_dir_a-ls.o): In function 
`decode_switches':
src/ls.c:1532: undefined reference to `libsinglebin_dir_ls_mode'
src/ls.c:1959: undefined reference to `libsinglebin_dir_ls_mode'
src/libsinglebin_ls.a(src_libsinglebin_ls_a-ls.o): In function 
`decode_switches':
src/ls.c:1532: undefined reference to `libsinglebin_ls_ls_mode'
src/ls.c:1959: undefined reference to `libsinglebin_ls_ls_mode'
src/libsinglebin_uname.a(src_libsinglebin_uname_a-uname.o): In function 
`_usage_uname':
src/uname.c:122: undefined reference to `libsinglebin_uname_uname_mode'
src/libsinglebin_uname.a(src_libsinglebin_uname_a-uname.o): In function 
`decode_switches':
src/uname.c:179: undefined reference to `libsinglebin_uname_uname_mode'
uname.c:241: undefined reference to `libsinglebin_uname_uname_mode'
uname.c:188: undefined reference to `libsinglebin_uname_uname_mode'
src/libsinglebin_vdir.a(src_libsinglebin_vdir_a-ls.o): In function 
`decode_switches':
ls.c:1532: undefined reference to `libsinglebin_vdir_ls_mode'
ls.c:1959: undefined reference to `libsinglebin_vdir_ls_mode'

thanks!
Pádraig.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]