Credits:
Matt Kraai - initial writeup
Mark Whitley - the remix
-Thomas Lundquist - Trying to keep it updated.
+Thomas Lundquist - trying to keep it updated
When doing this you should consider using the latest git HEAD.
This is a good thing if you plan to getting it committed into mainline.
First, write your applet. Be sure to include copyright information at the top,
such as who you stole the code from and so forth. Also include the mini-GPL
-boilerplate. Be sure to name the main function <applet>_main instead of main.
-And be sure to put it in <applet>.c. Usage does not have to be taken care of by
-your applet.
-Make sure to #include "libbb.h" as the first include file in your applet so
-the bb_config.h and appropriate platform specific files are included properly.
+boilerplate and Config.in/Kbuild/usage/applet.h snippets (more on that below
+in this document). Be sure to name the main function <applet>_main instead
+of main. And be sure to put it in <applet>.c. Make sure to #include "libbb.h"
+as the first include file in your applet.
For a new applet mu, here is the code that would go in mu.c:
-(busybox.h already includes most usual header files. You do not need
+(libbb.h already includes most usual header files. You do not need
#include <stdio.h> etc...)
*
* Copyright (C) [YEAR] by [YOUR NAME] <YOUR EMAIL>
*
- * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
*/
#include "libbb.h"
#include "other.h"
+//config:config MU
+//config: bool "MU"
+//config: default y
+//config: help
+//config: Returns an indeterminate value.
+
+//kbuild:lib-$(CONFIG_MU) += mu.o
+//applet:IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP))
+
+//usage:#define mu_trivial_usage
+//usage: "[-abcde] FILE..."
+//usage:#define mu_full_usage
+//usage: "Returns an indeterminate value\n"
+//usage: "\n -a First function"
+//usage: "\n -b Second function"
+
int mu_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int mu_main(int argc, char **argv)
{
#include "libbb.h"
#include "other.h"
+//kbuild:lib-y += function.o
+
int function(char *a)
{
return *a;
----end example code------
-Add <function_name>.o in the right alphabetically sorted place
-in libbb/Kbuild. You should look at the conditional part of
-libbb/Kbuild aswell.
+Remember about the kbuild snippet.
You should also try to find a suitable place in include/libbb.h for
the function declaration. If not, add it somewhere anyway, with or without
ifdefs to include or not.
-You can look at libbb/Config.in and try to find out if the function is
+You can look at libbb/Config.src and try to find out if the function is
tunable and add it there if it is.
+Kbuild/Config.in/usage/applets.h snippets in .c files
+-----------------------------------------------------
+
+The old way of adding new applets was to put all the information needed by the
+configuration and build system into appropriate files (namely: Kbuild.src and
+Config.src in new applet's directory) and to add the applet declaration and
+usage info text to include/applets.src.h and include/usage.src.h respectively.
+
+Since the scripts/gen_build_files.sh script had been introduced, the preferred
+way is to have all these declarations contained within the applet .c files.
+
+Every line intended to be processed by gen_build_files.sh should start as a
+comment without any preceding whitespaces and be followed by an appropriate
+keyword - kbuild, config, usage or applet - and a colon, just like shown in the
+first example above.
+
+
Placement / Directory
---------------------
Find the appropriate directory for your new applet.
-Make sure you find the appropriate places in the files, the applets are
-sorted alphabetically.
+Add the kbuild snippet to the .c file:
-Add the applet to Kbuild in the chosen directory:
+//kbuild:lib-$(CONFIG_MU) += mu.o
-lib-$(CONFIG_MU) += mu.o
+Add the config snippet to the .c file:
-Add the applet to Config.in in the chosen directory:
-
-config MU
- bool "MU"
- default n
- help
- Returns an indeterminate value.
+//config:config MU
+//config: bool "MU"
+//config: default y
+//config: help
+//config: Returns an indeterminate value.
Usage String(s)
---------------
-Next, add usage information for you applet to include/usage.h.
+Next, add usage information for your applet to the .c file.
This should look like the following:
- #define mu_trivial_usage \
- "-[abcde] FILES"
- #define mu_full_usage \
- "Returns an indeterminate value.\n\n" \
- "Options:\n" \
- "\t-a\t\tfirst function\n" \
- "\t-b\t\tsecond function\n" \
- ...
+//usage:#define mu_trivial_usage
+//usage: "[-abcde] FILE..."
+//usage:#define mu_full_usage
+//usage: "Returns an indeterminate value\n"
+//usage: "\n -a First function"
+//usage: "\n -b Second function"
+//usage: ...
If your program supports flags, the flags should be mentioned on the first
-line (-[abcde]) and a detailed description of each flag should go in the
-mu_full_usage section, one flag per line. (Numerous examples of this
-currently exist in usage.h.)
+line ([-abcde]) and a detailed description of each flag should go in the
+mu_full_usage section, one flag per line.
Header Files
------------
-Next, add an entry to include/applets.h. Be *sure* to keep the list
-in alphabetical order, or else it will break the binary-search lookup
-algorithm in busybox.c and the Gods of BusyBox smite you. Yea, verily:
-
-Be sure to read the top of applets.h before adding your applet.
+Finally add the applet declaration snippet. Be sure to read the top of
+applets.src.h before adding your applet - it contains important info
+on applet macros and conventions.
- /* all programs above here are alphabetically "less than" 'mu' */
- IF_MU(APPLET(mu, _BB_DIR_USR_BIN, _BB_SUID_DROP))
- /* all programs below here are alphabetically "greater than" 'mu' */
+//applet:IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP))
The Grand Announcement