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.