| ============================== |
| Introduction |
| ============================== |
| |
| The following document briefly describes the steps and methodologies used for |
| the new and improved Makefile system. |
| |
| ============================== |
| The Problem |
| ============================== |
| |
| The problem with the old Makefile system is that it was very difficult to |
| maintain and it lacked any sense of formal structure, thus developing for LTP |
| and including new targets was more difficult than it should have been |
| (maintenance). Furthermore, proper option-based cross-compilation was |
| impossible due to the fact that the Makefiles didn't support a prefixing |
| system, and the appropriate implicit / static rules hadn't been configured to |
| compile into multiple object directories for out-of-tree build support (ease of |
| use / functionality). Finally, there wasn't a means to setup dependencies |
| between components, such that if a component required libltp.a in order to |
| compile, it would go off and compile libltp.a first (ease of use). |
| |
| These items needed to be fixed to reduce maintenance nightmares for the |
| development community contributing to LTP, and the project maintainers. |
| |
| ============================== |
| Design |
| ============================== |
| |
| The system was designed such that including a single GNU Makefile compatible |
| set in each new directory component is all that's essentially required to |
| build the system. |
| |
| Say you had a directory like the following (with .c files in them which |
| directly tie into applications, e.g. baz.c -> baz): |
| |
| .../foo/ |
| |--> Makefile |
| | |
| --> bar/ |
| | |
| --> Makefile |
| | |
| --> baz.c |
| |
| Here's an example of how one would accomplish that: |
| |
| .../foo/Makefile: |
| # |
| # Copyright disclaimer goes here -- please use GPLv2. |
| # |
| |
| top_srcdir ?= .. |
| |
| include $(top_srcdir)/include/mk/env_pre.mk |
| include $(top_srcdir)/include/mk/generic_trunk_target.mk |
| |
| .../foo/bar/Makefile: |
| # |
| # Copyright disclaimer goes here -- please use GPLv2. |
| # |
| |
| top_srcdir ?= .. |
| |
| include $(top_srcdir)/include/mk/env_pre.mk |
| include $(top_srcdir)/include/mk/generic_leaf_target.mk |
| |
| ============================== |
| Make Rules and Make Variables |
| ============================== |
| |
| When using make rules, avoid writing ad hoc rules like: |
| |
| [prog]: [dependencies] |
| cc -I../../include $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS) \ |
| -o [prog] [dependencies] |
| |
| etc. This makes cross-compilation and determinism difficult, if not impossible. |
| Besides, implicit rules are your friends and as long as you use `MAKEOPTS=;' in |
| the top-level caller (or do $(subst r,$(MAKEOPTS)) to remove -r), the compile |
| will complete successfully, assuming all other prerequisites have been |
| fulfilled (libraries, headers, etc). |
| |
| $(AR) : The library archiver. |
| |
| $(CC) : The system C compiler. |
| |
| $(CXX) : The system C++ compiler. |
| |
| $(CPP) : The system C preprocessor. |
| |
| $(CFLAGS) : C compiler flags. |
| |
| $(CPPFLAGS) : Preprocessor flags, e.g. -I arguments. |
| |
| $(CXXFLAGS) : C++ compiler flags, e.g. -I arguments. |
| |
| $(DEBUG_CFLAGS) : Debug flags to pass to $(CC), -g, etc. |
| |
| $(DEBUG_CXXFLAGS) : Debug flags to pass to $(CXX). |
| |
| $(LD) : The system linker (typically $(CC), but not |
| necessarily). |
| |
| $(LDFLAGS) : What to pass in to the linker, including -L arguments |
| and other ld arguments, apart from -l library |
| includes (see $(LDLIBS)). |
| |
| This should be done in the $(CC) args passing style |
| when LD := $(CC), e.g. `-Wl,-foo', as opposed to |
| `-foo'. |
| |
| $(LDLIBS) : Libraries to pass to the linker (e.g. -lltp, etc). |
| |
| $(OPT_CFLAGS) : Optimization flags to pass into the C compiler, -O2, |
| etc. If you specify -O2 or higher, you should also |
| specify -fno-strict-aliasing, because of gcc |
| fstrict-aliasing optimization bugs in the tree |
| optimizer. Search for `fstrict-aliasing optimization |
| bug' with your favorite search engine. |
| |
| Examples of more recent bugs: |
| 1. tree-optimization/17510 |
| 2. tree-optimization/39100 |
| |
| Various bugs have occurred in the past due to buggy |
| logic in the tree-optimization portion of the gcc |
| compiler, from 3.3.x to 4.4. |
| |
| $(OPT_CXXFLAGS) : Optimization flags to pass to the C++ compiler. |
| |
| $(RANLIB) : What to run after archiving a library. |
| |
| $(WCFLAGS) : Warning flags to pass to $(CC), e.g. -Werror, |
| -Wall, etc. |
| |
| $(WCXXFLAGS) : Same as $(WCFLAGS), but for $(CXX). |
| |
| ============================== |
| Make System Variables |
| ============================== |
| |
| A series of variables are used within the make system that direct what actions |
| need to be taken. Rather than me listing the variables here, please with their |
| intended uses, please refer to the comments contained in |
| `.../include/mk/env_pre.mk'. |
| |
| ============================== |
| Guidelines and Recommendations |
| ============================== |
| |
| Of course, the GNU Make manual is key to understanding the Make system, but |
| here are the following sections and chapters I suggest reviewing: |
| |
| - implicit rules: http://www.gnu.org/software/make/manual/make.html#Implicit-Rules |
| - variables and expansion: http://www.gnu.org/software/make/manual/make.html#Using-Variables |
| - origin use: http://www.gnu.org/software/make/manual/make.html#Origin-Function |
| - vpath use: http://www.gnu.org/software/make/manual/make.html#Directory-Search |
| |
| ============================== |
| Before Committing |
| ============================== |
| |
| One should rebuild from scratch before committing. Please see INSTALL for more |
| details. |
| |
| ============================== |
| Other Errata |
| ============================== |
| |
| Please see TODO for any issues related to the Makefile infrastructure, and |
| build structure / source tree in general. |