# [Record] Tips for working with Buildroot
###### tags: `buildroot`, `environment paramters`, `Makefile`
[toc]
## Outline
In this note, I will share some tips when working with buildroot like
- **Tips1:** ***++A way to pass environment variables when make in Buildroot++***
- **Tips2:** ***++Using a branch name as FOO_VERSION in Buildroot++***
It is worthy noticing that my buildroot is
``` git
commit c0d9ba562c5522096d4ed70827c599c9a0e9aa7c (HEAD -> master, origin/master, origin/HEAD)
Author: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Date: Tue Oct 9 19:22:17 2018 +0200
nmap: use system liblinear
Use system liblinear instead of using included liblinear.
liblinear in buildroot is at version 2.20 released on December 2017
whereas liblinear in nmap has not been updated since 7 years (except for
liblinear.vcxproj which has been updated 2 years ago)
Do not use --with-liblinear option as otherwise nmap will forget to add
-llinear to LIBS due to the following line in configure.ac:
if test $have_liblinear != yes; then
AC_CHECK_HEADERS([linear.h],
AC_CHECK_LIB(linear, predict, [have_liblinear=yes; LIBLINEAR_LIBS="-llinear"; break],, [-lm])
)
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
```
---
## **Tips 1:** ***++A way to pass environment variables when make in Buildroot++***
### Preface
I am going to show the way to pass ***make environment variables*** from buildroot to a package we'd like to build. These environment variables are not only mostly common variables used as names of programs in built-in rules as shown in **++Annex A++** but also others you'd like to define. Here, we will give an example to show the way to define a MARCO through makefile **-D** option in CFLAGS.
### Demo
Firstly, assume the target package is **libfoo** which is a generic package. Secondly, we have to modify ***libfoo*.*mk*** in buildroot. Finally, we amend the Makefile of **libfoo** in the repository.
#### In **libfoo**.**mk**
Below shows ***libfoo*.*mk*** where I add an environment variable **LIBFOO_TARGET_MAKE_ENV** in line 18 ~ 25. And **LIBFOO_TARGET_MAKE_ENV** will be pass to libfoo's Makefile when we build or make it.
```Makefile=
################################################################################
#
# libfoo
#
################################################################################
LIBFOO_VERSION = orgin/master
LIBFOO_SITE = git@192.168.10.1:libfoo.git
LIBFOO_SITE_METHOD = git
LIBFOO_LICENSE = GPL-3.0+
LIBFOO_INSTALL_STAGING = YES
LIBFOO_CONFIG_SCRIPTS = libfoo-config
LIBFOO_DEPENDENCIES = host-libaaa libbbb
#BR2_XXX_FW_VERSION may be define in .config and assume it is 3.0
BUILD_FW_VERSION = $(call qstrip, (BR2_XXX_FW_VERSION))
PRODUCT_NAME = Firebolt
MY_LIBFOO_VERSION = $(shell tmp=$(LIBFOO_VERSION); echo $${tmp:0:4})
LIBFOO_TARGET_MAKE_ENV += MY_CPU=MIPS
LIBFOO_TARGET_MAKE_ENV += MY_BUILD_TYPE=hurricane
LIBFOO_TARGET_MAKE_ENV += MY_TARGET_TYPE=hotspring
LIBFOO_TARGET_MAKE_ENV += MY_LR_EXE_LIBS+= "-labc -labb -laba"
LIBFOO_TARGET_MAKE_ENV += MY_COMPILATION_SWITCHES+="-DVAR1 -DVAR2 -DVAR3"
LIBFOO_TARGET_MAKE_ENV += YOUR_COMPILATION_SWITCHES+= \
"-D MY_SOFTWARE_VERSION='\"$(MY_LIBFOO_VERSION)\"' \
-D MY_FW_VERSION='\"$(BUILD_FW_VERSION)\"' \
-D MY_PRODUCT_NAME='\"$(PRODUCT_NAME)\"'"
LIBFOO_OTHER_MAKE_ENV = $(shell tmp=$(LIBFOO_VERSION); echo $${tmp:6:11})
define LIBFOO_BUILD_CMDS
$(LIBFOO_TARGET_MAKE_ENV) $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) all
endef
define LIBFOO_INSTALL_STAGING_CMDS
$(INSTALL) -D -m 0755 $(@D)/libfoo.a $(STAGING_DIR)/usr/lib/libfoo.a
$(INSTALL) -D -m 0644 $(@D)/foo.h $(STAGING_DIR)/usr/include/foo.h
$(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(STAGING_DIR)/usr/lib
endef
define LIBFOO_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(TARGET_DIR)/usr/lib
$(INSTALL) -d -m 0755 $(TARGET_DIR)/etc/foo.d
endef
define LIBFOO_USERS
foo -1 libfoo -1 * - - - LibFoo daemon
endef
define LIBFOO_DEVICES
/dev/foo c 666 0 0 42 0 - - -
endef
define LIBFOO_PERMISSIONS
/bin/foo f 4755 foo libfoo - - - - -
endef
$(eval $(generic-package))
```
Notice line 22 that it is equivalent to
``` C
#define VAR1
#define VAR2
#define VAR3
```
And, line 23 ~ 26 are equivalent to
``` C
#define MY_SOFTWARE_VERSION "origin"
#define MY_FW_VERSION "3.0"
#define MY_PRODUCT_NAME "Firebolt"
```
Line 27 is equivalent to
```
LIBFOO_OTHER_MAKE_ENV=master
```
---
#### In Makefile of libfoo.git
Below is the part we have to add to Makefile in libfoo.git.
``` shell=
MY_SYSTEM_SWITCHES += -DAAA -DBBB_WANTED -DCCC_WANTED \
$(MY_COMPILATION_SWITCHES) \
$(YOUR_COMPILATION_SWITCHES)
MY_OTHER_ENV = $(LIBFOO_OTHER_MAKE_ENV)
$(info MY_OTHER_ENV = $(MY_OTHER_ENV))
```
And we can reference to these symbols directly in main_libfoo.c as shown below.
```C=
#include <stdio.h>
int main(void)
{
#ifdef VAR1
printf("MY_SOFTWARE_VERSION =%s\n", MY_SOFTWARE_VERSION);
#endif
#ifdef VAR2
printf("MY_FW_VERSION =%s\n", MY_FW_VERSION);
#endif
#ifdef VAR3
printf("MY_PRODUCT_NAME =%s\n", MY_PRODUCT_NAME);
#endif
return 0;
}
```
And the outcomes are:
``` shell
[tomas@ buildroot_example]$ make -j8
...
MY_OTHER_ENV = master
...
[tomas@ buildroot_example]$ ./mylibfoo
MY_SOFTWARE_VERSION = origin
MY_FW_VERSION = 3.0
MY_PRODUCT_NAME = Firebolt
```
## **Tips2:** ***++Using a branch name as FOO_VERSION in Buildroot++***
According to **[17.5.2. generic-package reference](https://buildroot.org/downloads/manual/manual.html#_infrastructure_for_packages_with_specific_build_systems)** in *The Buildroot user manual*,
>LIBFOO_VERSION, mandatory, must contain the version of the package. Note that if HOST_LIBFOO_VERSION doesn’t exist, it is assumed to be the same as LIBFOO_VERSION. It can also be a revision number or a tag for packages that are fetched directly from their version control system. Examples:
>a version for a release tarball: LIBFOO_VERSION = 0.1.2
a sha1 for a git tree: LIBFOO_VERSION = cb9d6aa9429e838f0e54faa3d455bcbab5eef057
a tag for a git tree LIBFOO_VERSION = v0.1.2
It is worthy noticing that
>Note: **Using a branch name as FOO_VERSION is not supported**, because it does not and can not work as people would expect it should:
>due to local caching, Buildroot will not re-fetch the repository, so people who expect to be able to follow the remote repository would be quite surprised and disappointed;
because two builds can never be perfectly simultaneous, and because the remote repository may get new commits on the branch anytime, two users, using the same Buildroot tree and building the same configuration, may get different source, thus rendering the build non reproducible, and people would be quite surprised and disappointed.
This means when you use a branch name as FOO_VERSION, i.e.,
```
FOO_VERSION = origin/master
```
When the first time we build FOO, Buildroot will download the source of FOO in the path ***BR2_DL_DIR="$(TOPDIR)/dl"***. But, for the second or even more times we build it, Buildroot will not download it again once the FOO-origin_master.tar.gz exists in dl folder. If someone push a commit to this branch, we will not get the correct commit.
The way to make it work fine is to ***++delete the folder dl/FOO.++***
# Annex
## A. Variables Used by Implicit Rules
>**AR**
Archive-maintaining program; default ‘ar’.
>**AS**
Program for compiling assembly files; default ‘as’.
>**CC**
Program for compiling C programs; default ‘cc’.
>**CXX**
Program for compiling C++ programs; default ‘g++’.
>**CPP**
Program for running the C preprocessor, with results to standard output; default ‘$(CC) -E’.
>**FC**
Program for compiling or preprocessing Fortran and Ratfor programs; default ‘f77’.
>**M2C**
Program to use to compile Modula-2 source code; default ‘m2c’.
>**PC**
Program for compiling Pascal programs; default ‘pc’.
>**CO**
Program for extracting a file from RCS; default ‘co’.
>**GET**
Program for extracting a file from SCCS; default ‘get’.
>**LEX**
Program to use to turn Lex grammars into source code; default ‘lex’.
>**YACC**
Program to use to turn Yacc grammars into source code; default ‘yacc’.
>**LINT**
Program to use to run lint on source code; default ‘lint’.
>**MAKEINFO**
Program to convert a Texinfo source file into an Info file; default ‘makeinfo’.
>**TEX**
Program to make TeX DVI files from TeX source; default ‘tex’.
>**TEXI2DVI**
Program to make TeX DVI files from Texinfo source; default ‘texi2dvi’.
>**WEAVE**
Program to translate Web into TeX; default ‘weave’.
>**CWEAVE**
Program to translate C Web into TeX; default ‘cweave’.
>**TANGLE**
Program to translate Web into Pascal; default ‘tangle’.
>**CTANGLE**
Program to translate C Web into C; default ‘ctangle’.
>**RM**
Command to remove a file; default ‘rm -f’.
Here is a table of variables whose values are additional arguments for the programs above. The default values for all of these is the empty string, unless otherwise noted.
>**ARFLAGS**
Flags to give the archive-maintaining program; default ‘rv’.
>**ASFLAGS**
Extra flags to give to the assembler (when explicitly invoked on a ‘.s’ or ‘.S’ file).
>**CFLAGS**
Extra flags to give to the C compiler.
>**CXXFLAGS**
Extra flags to give to the C++ compiler.
>**COFLAGS**
Extra flags to give to the RCS co program.
>**CPPFLAGS**
Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
>**FFLAGS**
Extra flags to give to the Fortran compiler.
>**GFLAGS**
Extra flags to give to the SCCS get program.
>**LDFLAGS**
Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.
>**LDLIBS**
Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.
>**LFLAGS**
Extra flags to give to Lex.
>**YFLAGS**
Extra flags to give to Yacc.
>**PFLAGS**
Extra flags to give to the Pascal compiler.
>**RFLAGS**
Extra flags to give to the Fortran compiler for Ratfor programs.
>**LINTFLAGS**
Extra flags to give to lint.
# Reference
https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
https://buildroot.org/downloads/manual/manual.html