diff --git a/Makefile b/Makefile index 3ed445e7..82417d19 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,11 @@ # clean clean built binaries (not the documentation) # clean-all clean as above, clean docs and generated files # +# All-in-one binary (busybox style): +# btrfs.box single binary with functionality of mkfs.btrfs, btrfs-image, +# btrfs-convert and btrfstune, selected by the file name +# btrfs.box.static dtto, static version +# # Tuning by variables (environment or make arguments): # V=1 verbose, print command lines (default: quiet) # C=1 run checker before compilation (default checker: sparse) @@ -226,6 +231,19 @@ endif MAKEOPTS = --no-print-directory Q=$(Q) +# built-in sources into "busybox", all files that contain the main function and +# are not compiled standalone +progs_box_main = btrfs.o mkfs/main.o image/main.o convert/main.o \ + btrfstune.o + +progs_box_all_objects = $(mkfs_objects) $(image_objects) $(convert_objects) +progs_box_all_static_objects = $(static_mkfs_objects) $(static_image_objects) \ + $(static_convert_objects) + +progs_box_objects = $(filter-out %/main.o, $(progs_box_all_objects)) \ + $(patsubst %.o, %.box.o, $(progs_box_main)) +progs_box_static_objects = $(filter-out %/main.static.o, $(progs_box_all_static_objects)) \ + $(patsubst %.o, %.box.static.o, $(progs_box_main)) # Programs to install. progs_install = btrfs mkfs.btrfs btrfs-map-logical btrfs-image \ @@ -337,6 +355,14 @@ endif $(Q)$(CC) $(STATIC_CFLAGS) -c $< -o $@ $($(subst /,_,$(subst -,_,$(@:%.static.o=%)-cflags))) \ $($(subst -,_,btrfs-$(@:%/$(notdir $@)=%)-cflags)) +%.box.o: %.c + @echo " [CC] $@" + $(Q)$(CC) -DENABLE_BOX=1 $(CFLAGS) $(btrfs_convert_cflags) -c $< -o $@ + +%.box.static.o: %.c + @echo " [CC] $@" + $(Q)$(CC) -DENABLE_BOX=1 $(STATIC_CFLAGS) $(btrfs_convert_cflags) -c $< -o $@ + all: $(progs_build) $(libs_build) $(BUILDDIRS) ifeq ($(PYTHON_BINDINGS),1) all: libbtrfsutil_python @@ -489,6 +515,25 @@ btrfs.static: btrfs.static.o $(static_objects) $(static_cmds_objects) $(static_l @echo " [LD] $@" $(Q)$(CC) -o $@ $^ $(STATIC_LDFLAGS) $(STATIC_LIBS) $(STATIC_LIBS_COMP) +btrfs.box: btrfs.box.o $(objects) $(cmds_objects) $(progs_box_objects) $(libs_static) + @echo " [LD] $@" + $(Q)$(CC) -o $@ $^ $(btrfs_convert_libs) $(LDFLAGS) $(LIBS) $(LIBS_COMP) + +btrfs.box.static: btrfs.box.static.o $(static_objects) $(static_cmds_objects) $(progs_box_static_objects) $(static_libbtrfs_objects) $(static_libbtrfsutil_objects) + @echo " [LD] $@" + $(Q)$(CC) $(STATIC_CFLAGS) -o $@ $^ $(btrfs_convert_libs) \ + $(STATIC_LDFLAGS) $(STATIC_LIBS) $(STATIC_LIBS_COMP) + +box-links: btrfs.box + @echo " [LN] mkfs.btrfs" + $(Q)$(LN_S) -sf btrfs.box mkfs.btrfs + @echo " [LN] btrfs-image" + $(Q)$(LN_S) -sf btrfs.box btrfs-image + @echo " [LN] btrfs-convert" + $(Q)$(LN_S) -sf btrfs.box btrfs-convert + @echo " [LN] btrfstune" + $(Q)$(LN_S) -sf btrfs.box btrfstune + # For backward compatibility, 'btrfs' changes behaviour to fsck if it's named 'btrfsck' btrfsck: btrfs @echo " [LN] $@" @@ -645,6 +690,7 @@ clean: $(CLEANDIRS) cmds/*.o cmds/*.o.d common/*.o common/*.o.d \ ioctl-test quick-test library-test library-test-static \ mktables btrfs.static mkfs.btrfs.static fssum \ + btrfs.box btrfs.box.static \ $(check_defs) \ $(libs) $(lib_links) \ $(progs_static) \ diff --git a/btrfs.c b/btrfs.c index d2d5315a..6c8aabe2 100644 --- a/btrfs.c +++ b/btrfs.c @@ -24,6 +24,7 @@ #include "cmds/commands.h" #include "common/utils.h" #include "common/help.h" +#include "common/box.h" static const char * const btrfs_cmd_group_usage[] = { "btrfs [--help] [--version] [--format ] [...] []", @@ -154,15 +155,33 @@ int handle_command_group(const struct cmd_struct *cmd, int argc, static const struct cmd_group btrfs_cmd_group; static const char * const cmd_help_usage[] = { - "btrfs help [--full]", + "btrfs help [--full] [--box]", "Display help information", "", "--full display detailed help on every command", + "--box show list of built-in tools (busybox style)", NULL }; static int cmd_help(const struct cmd_struct *unused, int argc, char **argv) { + int i; + + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "--box") == 0) { +#if ENABLE_BOX + printf("Standalone tools built-in in the busybox style:\n"); + printf("- mkfs.btrfs\n"); + printf("- btrfs-image\n"); + printf("- btrfs-convert\n"); + printf("- btrfstune\n"); + printf("- btrfs-find-root\n"); +#else + printf("No standalone tools built-in in the busybox style\n"); +#endif + exit(0); + } + } help_command_group(&btrfs_cmd_group, argc, argv); return 0; } @@ -331,6 +350,16 @@ int main(int argc, char **argv) if (!strcmp(bname, "btrfsck")) { argv[0] = "check"; +#ifdef ENABLE_BOX + } else if (!strcmp(bname, "mkfs.btrfs")) { + return mkfs_main(argc, argv); + } else if (!strcmp(bname, "btrfs-image")) { + return image_main(argc, argv); + } else if (!strcmp(bname, "btrfs-convert")) { + return convert_main(argc, argv); + } else if (!strcmp(bname, "btrfstune")) { + return btrfstune_main(argc, argv); +#endif } else { int shift; diff --git a/btrfstune.c b/btrfstune.c index ce028474..afa3aae3 100644 --- a/btrfstune.c +++ b/btrfstune.c @@ -33,6 +33,7 @@ #include "common/utils.h" #include "volumes.h" #include "common/help.h" +#include "common/box.h" static char *device; static int force = 0; @@ -480,7 +481,7 @@ static void print_usage(void) printf("\t--help print this help\n"); } -int main(int argc, char *argv[]) +int BOX_MAIN(btrfstune)(int argc, char *argv[]) { struct btrfs_root *root; unsigned ctree_flags = OPEN_CTREE_WRITES; diff --git a/common/box.h b/common/box.h new file mode 100644 index 00000000..f3fd312d --- /dev/null +++ b/common/box.h @@ -0,0 +1,41 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef __BTRFS_BOX_H__ +#define __BTRFS_BOX_H__ + +/* + * For tools that can co-exist in a single binary and their main() gets + * switched by the file name. + */ +#ifdef ENABLE_BOX +#define BOX_MAIN(name) name##_main +#define DECLARE_BOX_MAIN(name) int name##_main(int argc, char **argv) + +/* + * Declarations of the built-in tools, pairing with actual definitions of the + * respective main function + */ +DECLARE_BOX_MAIN(mkfs); +DECLARE_BOX_MAIN(image); +DECLARE_BOX_MAIN(convert); +DECLARE_BOX_MAIN(btrfstune); + +#else +#define BOX_MAIN(standalone) main +#endif + +#endif diff --git a/common/help.c b/common/help.c index b9d3dde1..189a1d35 100644 --- a/common/help.c +++ b/common/help.c @@ -473,6 +473,7 @@ void help_command_group(const struct cmd_group *grp, int argc, char **argv) if (argc > 1) { if (!strcmp(argv[1], "--full")) full = 1; + /* The option --box is handled in the caller */ } usage_command_group(grp, full, false); diff --git a/convert/main.c b/convert/main.c index 68c4eb61..9711874b 100644 --- a/convert/main.c +++ b/convert/main.c @@ -104,6 +104,7 @@ #include "convert/source-fs.h" #include "kernel-lib/crc32c.h" #include "common/fsfeatures.h" +#include "common/box.h" extern const struct btrfs_convert_operations ext2_convert_ops; extern const struct btrfs_convert_operations reiserfs_convert_ops; @@ -1713,7 +1714,7 @@ static void print_usage(void) printf("\treiserfs: %s\n", BTRFSCONVERT_REISERFS ? "yes" : "no"); } -int main(int argc, char *argv[]) +int BOX_MAIN(convert)(int argc, char *argv[]) { int ret; int packing = 1; diff --git a/image/main.c b/image/main.c index 9c7adb9a..28ef1609 100644 --- a/image/main.c +++ b/image/main.c @@ -39,6 +39,7 @@ #include "common/device-utils.h" #include "image/metadump.h" #include "image/sanitize.h" +#include "common/box.h" #define MAX_WORKER_THREADS (32) @@ -2590,7 +2591,7 @@ static void print_usage(int ret) exit(ret); } -int main(int argc, char *argv[]) +int BOX_MAIN(image)(int argc, char *argv[]) { char *source; char *target; diff --git a/mkfs/main.c b/mkfs/main.c index 383379e6..8dbec071 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -47,6 +47,7 @@ #include "mkfs/rootdir.h" #include "kernel-lib/crc32c.h" #include "common/fsfeatures.h" +#include "common/box.h" static int verbose = 1; @@ -785,7 +786,7 @@ out: return ret; } -int main(int argc, char **argv) +int BOX_MAIN(mkfs)(int argc, char **argv) { char *file; struct btrfs_root *root; diff --git a/tests/build-tests.sh b/tests/build-tests.sh index 15db42af..cb718a42 100755 --- a/tests/build-tests.sh +++ b/tests/build-tests.sh @@ -54,6 +54,9 @@ function build_make_targets() { # defaults, static target=static buildme + # defaults, busybox + target='btrfs.box btrfs.box.static' + buildme # defaults, 32bit target="EXTRA_CFLAGS=-m32" buildme