Project

General

Profile

BuildSystem » History » Revision 7

Revision 6 (fixeria, 03/14/2023 10:24 PM) → Revision 7/12 (fixeria, 03/14/2023 10:25 PM)

h1. The Build System 

 The build system is basically a suite of tools that helps developers to "translate" source code files into executable binaries and libraries. Examples of such systems are GNU Make, GNU Autotools, CMake, QMake, and Ninja. The majority of Osmocom projects is employing "GNU Autotools":https://en.wikipedia.org/wiki/GNU_Autotools, except these very few using CMake (mostly GNU Radio related projects) and hand-written Makefiles. Thus this page will be focusing on the GNU Autotools, which is supposed to make things simple for all of us, but sometimes becomes a PITA and a source of confusion for many. 

 h2. GNU Autotools Essentials 

 GNU Autotools includes the following tools: 

 * "Automake":https://www.gnu.org/software/automake/ - a tool for automatically generating @Makefile.in@ files, 
 * "Autoconf":https://www.gnu.org/software/autoconf/ - a tool for generating @configure@ scripts, and 
 * "Libtool":https://www.gnu.org/software/libtool/ - a tool for building static and shared libraries. 

 These tools are usually available in package repositories of many Linux distributions. 

 h2. GNU Autotools Basic Usage 

 The usual sequence of commands is as follows: 

 <pre> 
 $ autoreconf -fi 
 $ ./configure 
 $ make 
 $ make check    # optionally 
 $ sudo make install 
 </pre> 

 @autoreconf@ scans the current directory for @configure.ac@ and @Makefile.am@ taking them as the input, converts @Makefile.am@ files to @Makefile.in@, and generates the @configure@ script. The @configure@ script performs dozens of checks, finds suitable compilers and linkers, scans for @Makefile.in@ files and generates the usual @Makefile@ files from them. Finally, @make@ follows the rules listed in automatically generated @Makefile@ files, and invokes compilers, linkers, and other tools on the source files. 

 h2. GNU Autotools For Developers 

 This *Work-in-Progress* section is for those who want to understand and write their own @configure.ac@ and @Makefile.am@ files. It's not a complete guide and definitely not for beginners, please refer to documentation of the respective GNU projects. The main focus here in on common problems and corner cases we faced during development. 

 h3. Weird syntax 

 Yes, it is. Even worse, while a typical @Makefile.am@ mostly contains specifically-named variables listing source files and their dependencies (i.e. libraries), @configure.ac@ employs rather archaic "m4":https://www.gnu.org/software/m4/ language, so you may often find yourself googling the basic syntax of simple constructs like conditional statements and never remembering them. The good news is that you can include the usual Makefile-like rules in @Makefile.am@ files, but this should be avoided unless it's absolutely necessary due to potential portability problems. 

 h3. @Makefile.am@ variables 

 There are not that many of them, but it's easy to get confused. 

 h4. Binaries 

 * @bin_PROGRAMS@ - executable files, which will be installed during @make install@ 
 * @noinst_PROGRAMS@ - executable files, which will *not* be installed during @make install@ 
 * @check_PROGRAMS@ - executable files, which will only be compiled during @make check@ and will *not* be installed during @make install@ 

 TIP: It's recommended to use @check_PROGRAMS@ for tests, so that they won't be compiled during @make all@. 

 h4. Libraries 

 There exist static and shared libraries, see https://stackoverflow.com/questions/2649334/difference-between-static-and-shared-libraries. 
 Libtool adds another layer of discrimination: regular static libraries (@.a@) and libtool archives (@.la@), see https://www.linuxfromscratch.org/blfs/view/svn/introduction/la-files.html. 

 * @lib_LTLIBRARIES@ - list of shared libraries (libtool @.*la@ archives, later @*.so@ files), to be installed during @make install@ 
 * @noinst_LTLIBRARIES@ - list of static libraries (libtool @.*la@ archives), not installed during @make install@ 
 * @noinst_LIBRARIES@ - list of static libraries (regular @.a@ archives), not installed during @make install@ 

 libtool @*.la@ libraries can depend on other libraries, regular @*.a@ libraries cannot. Here is an example: 

 <pre> 
 # static libtool library, not going to be installed 
 noinst_LTLIBRARIES = libosmo-foo.la 
 libosmo_foo_la_SOURCES = src/foo.c 
 libosmo_foo_la_LIBADD = $(TALLOC_LIBS) 

 # shared libtool library, to be installed, depends on libosmo-foo.la 
 lib_LTLIBRARIES = libosmo-bar.la 
 libosmo_bar_la_SOURCES = src/bar.c 
 libosmo_bar_la_LIBADD = \ 
         $(top_builddir)/src/libosmo-foo.la 
         $(LIBOSMOCORE_LIBS) \ 
         $(LIBOSMOGSM_LIBS) \ 
         $(NULL) 
 </pre> 

 In the example above @libosmo-bar.la@ (dynamic lib) depends on @libosmo-foo.la@ (static lib). Among with @LIBOSMOCORE_LIBS@ and @LIBOSMOGSM_LIBS@, the resulting @libosmo-bar.so@ will additionally depend on @$(TALLOC_LIBS)@ because it's a dependency of @libosmo-foo.la@. 

 NOTE: It's recommended to list repository-local libs (@libosmo-foo.la@ in the example above) first, not after any of the external dependencies (e.g. @$(LIBOSMOCORE_LIBS)@). Otherwise you may experience weird problems when running binaries within the repository, loading system-installed libs instead of the local ones. 

 h4. AM_CPPFLAGS, AM_CFLAGS, AM_CXXFLAGS 

 * @AM_CPPFLAGS@ is for the *preprocessor flags* like @-I$(top_srcdir)/include@ or @-DHAVE_FOOBAR@ 
 * @AM_CFLAGS@ is for the *C compiler flags* applying to C source files only 
 ** This is where you put stuff like @$(LIBOSMOCORE_CFLAGS)@ 
 ** Avoid putting @-O3@, @-g@, @-ggdb@ there, let the user decide of these flags 
 *** One exception is @-Wall@, and sometimes @-g@ in tests 
 * @AM_CXXFLAGS@ is similar to @AM_CFLAGS@, but applies to C++ source files only 

 These variables apply to all binaries and libraries within the current file. 
 You can overwrite them using per-binary/-library @osmo_app_CPPFLAGS@, @osmo_app_CFLAGS@, and @osmo_app_CXXFLAGS@ variables. 

 <pre> 
 AM_CPPFLAGS = -I$(top_srcdir)/include 
 AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) 

 # global AM_CPPFLAGS and AM_CFLAGS apply to osmo-app 
 bin_PROGRAMS = osmo-app 
 osmo_app_SOURCES = app.c 

 # osmo-app wants to have additional CFLAGS 
 osmo_app_CFLAGS = $(AM_CFLAGS) $(LIBOSMO_FOO_CFLAGS) 

 # osmo-app wants to redefine global CFLAGS 
 osmo_app_CFLAGS = $(LIBOSMO_BAR_CFLAGS) 
 </pre> 

 NOTE: In some projects you may see both preprocessor flags and compiler flags in @AM_CPPFLAGS@. This works because the compiler usually comes with a preprocessor, and the resulting Makefile rule looks like this: @$(CC) @gcc $(AM_CPPFLAGS) $(AM_CFLAGS) ...@. Though it's still desirable to have preprocessor and compiler flags in the proper variables, at least for the sake of clarity. 

 h4. AM_LDFLAGS vs LDADD, _LDADD and _LIBADD 

 * @AM_LDFLAGS@ is for the *liker flags* like @-version-info@, @-no-install@,    @-no-undefined@ 
 * @LDADD@ is a list of libraries that implicitly applies to all binaries and libs within the current file (unless overridden) 
 * @osmo_app_LDADD@ is a list of libraries for @osmo-app@ binary (not for libraries) 
 * @libosmo_lib_LIBADD@ is a list of libraries for @libosmo-lib@ library (not for binaries) 

 NOTE: It's a common mistake to put libraries into @AM_LDFLAGS@, please use the other three variables for that.    The key difference is that @AM_LDFLAGS@ appears first in the linker's command line, while the @LDADD@/@LIBADD@ ones appear last.    By having libraries listed in @AM_LDFLAGS@, you may experience weird problems running tests from @check_PROGRAMS@, which may load system-installed libraries instead of the repository-local ones. 

 TIP: It's a good practice to put @-no-install@ to @AM_LDFLAGS@ in @tests/Makefile.am@. This option should be used for any executables which are used only for testing, or for generating other files and are consequently never installed.    By specifying this option, we are telling Libtool that the executable it links will only ever be executed from where it is built in the build tree.    Libtool is usually able to considerably speed up the link process for such executables. 

 TIP: Using @-no-undefined@ (@AM_LDFLAGS@) is desirable for libraries which do not depend on external symbols defined in apps linking against them.
Add picture from clipboard (Maximum size: 48.8 MB)