Dave Barach | 8e83bcb | 2018-08-09 16:12:20 -0400 | [diff] [blame] | 1 | Introduction to build-root/Makefile |
| 2 | =================================== |
| 3 | |
| 4 | The vpp build system consists of a top-level Makefile, a data-driven |
| 5 | build-root/Makefile, and a set of makefile fragments. The various parts |
| 6 | come together as the result of a set of well-thought-out conventions. |
| 7 | |
| 8 | This section describes build-root/Makefile in some detail. |
| 9 | |
| 10 | Repository Groups and Source Paths |
| 11 | ---------------------------------- |
| 12 | |
| 13 | Current vpp workspaces comprise a single repository group. The file |
| 14 | .../build-root/build-config.mk defines a key variable called |
| 15 | SOURCE\_PATH. The SOURCE\_PATH variable names the set of repository |
| 16 | groups. At the moment, there is only one repository group. |
| 17 | |
| 18 | Single pass build system, dependencies and components |
| 19 | ----------------------------------------------------- |
| 20 | |
| 21 | The vpp build system caters to components built with GNU autoconf / |
| 22 | automake. Adding such components is a simple process. Dealing with |
| 23 | components which use BSD-style raw Makefiles is a more difficult. |
| 24 | Dealing with toolchain components such as gcc, glibc, and binutils can |
| 25 | be considerably more complicated. |
| 26 | |
| 27 | The vpp build system is a **single-pass** build system. A partial order |
| 28 | must exist for any set of components: the set of (a before b) tuples |
| 29 | must resolve to an ordered list. If you create a circular dependency of |
| 30 | the form; (a,b) (b,c) (c,a), gmake will try to build the target list, |
| 31 | but there’s a 0.0% chance that the results will be pleasant. Cut-n-paste |
| 32 | mistakes in .../build-data/packages/.mk can produce confusing failures. |
| 33 | |
| 34 | In a single-pass build system, it’s best to separate libraries and |
| 35 | applications which instantiate them. For example, if vpp depends on |
| 36 | libfoo.a, and myapp depends on both vpp and libfoo.a, it's best to place |
| 37 | libfoo.a and myapp in separate components. The build system will build |
| 38 | libfoo.a, vpp, and then (as a separate component) myapp. If you try to |
| 39 | build libfoo.a and myapp from the same component, it won’t work. |
| 40 | |
| 41 | If you absolutely, positively insist on having myapp and libfoo.a in the |
| 42 | same source tree, you can create a pseudo-component in a separate .mk |
| 43 | file in the .../build-data/packages/ directory. Define the code |
| 44 | phoneycomponent\_source = realcomponent, and provide manual |
| 45 | configure/build/install targets. |
| 46 | |
| 47 | Separate components for myapp, libfoo.a, and vpp is the best and easiest |
| 48 | solution. However, the “mumble\_source = realsource” degree of freedom |
| 49 | exists to solve intractable circular dependencies, such as: to build |
| 50 | gcc-bootstrap, followed by glibc, followed by “real” gcc/g++ [which |
| 51 | depends on glibc too]. |
| 52 | |
| 53 | .../build-root |
| 54 | -------------- |
| 55 | |
| 56 | The .../build-root directory contains the repository group specification |
| 57 | build-config.mk, the main Makefile, and the system-wide set of |
| 58 | autoconf/automake variable overrides in config.site. We'll describe |
| 59 | these files in some detail. To be clear about expectations: the main |
| 60 | Makefile and config.site file are subtle and complex. It's unlikely that |
| 61 | you'll need or want to modify them. Poorly planned changes in either |
| 62 | place typically cause bugs that are difficult to solve. |
| 63 | |
| 64 | .../build-root/build-config.mk |
| 65 | ------------------------------ |
| 66 | |
| 67 | As described above, the build-config.mk file is straightforward: it sets |
| 68 | the make variable SOURCE\_PATH to a list of repository group absolute |
| 69 | paths. |
| 70 | |
| 71 | The SOURCE\_PATH variable If you choose to move a workspace, make sure |
| 72 | to modify the paths defined by the SOURCE\_PATH variable. Those paths |
| 73 | need to match changes you make in the workspace paths. For example, if |
| 74 | you place the vpp directory in the workspace of a user named jsmith, you |
| 75 | might change the SOURCE\_PATH to: |
| 76 | |
| 77 | SOURCE\_PATH = /home/jsmithuser/workspace/vpp |
| 78 | |
| 79 | The "out of the box" setting should work 99.5% of the time: |
| 80 | |
| 81 | :: |
| 82 | |
| 83 | SOURCE_PATH = $(CURDIR)/.. |
| 84 | |
| 85 | .../vpp/build-root/Makefile |
| 86 | --------------------------- |
| 87 | |
| 88 | The main Makefile is complex in a number of dimensions. If you think you |
| 89 | need to modify it, it's a good idea to do some research, or ask for |
| 90 | advice before you change it. |
| 91 | |
| 92 | The main Makefile was organized and designed to provide the following |
| 93 | characteristics: excellent performance, accurate dependency processing, |
| 94 | cache enablement, timestamp optimizations, git integration, |
| 95 | extensibility, builds with cross-compilation tool chains, and builds |
| 96 | with embedded Linux distributions. |
| 97 | |
| 98 | If you really need to do so, you can build double-cross tools with it, |
| 99 | with a minimum amount of fuss. For example, you could: compile gdb on |
| 100 | x86\_64, to run on PowerPC, to debug the Xtensa instruction set. |
| 101 | |
| 102 | The PLATFORM variable |
| 103 | --------------------- |
| 104 | |
| 105 | The PLATFORM make/environment variable controls a number of important |
| 106 | characteristics, primarily: |
| 107 | |
| 108 | - CPU architecture |
| 109 | - The list of images to build. |
| 110 | |
| 111 | With respect to .../build-root/Makefile, the list of images to build is |
| 112 | specified by the target. For example: |
| 113 | |
| 114 | :: |
| 115 | |
| 116 | make PLATFORM=vpp TAG=vpp_debug install-deb |
| 117 | |
| 118 | builds vpp debug Debian packages. |
| 119 | |
| 120 | The main Makefile interprets $PLATFORM by attempting to "-include" the |
| 121 | file /build-data/platforms.mk: |
| 122 | |
| 123 | :: |
| 124 | |
| 125 | $(foreach d,$(FULL_SOURCE_PATH), \ |
| 126 | $(eval -include $(d)/platforms.mk)) |
| 127 | |
| 128 | By convention, we don't define **platforms** in the |
| 129 | ...//build-data/platforms.mk file. |
| 130 | |
| 131 | In the vpp case, we search for platform definition makefile fragments in |
| 132 | .../vpp/build-data/platforms.mk, as follows: |
| 133 | |
| 134 | :: |
| 135 | |
| 136 | $(foreach d,$(SOURCE_PATH_BUILD_DATA_DIRS), \ |
| 137 | $(eval -include $(d)/platforms/*.mk)) |
| 138 | |
| 139 | With vpp, which uses the "vpp" platform as discussed above, we end up |
| 140 | "-include"-ing .../vpp/build-data/platforms/vpp.mk. |
| 141 | |
| 142 | The platform-specific .mk fragment |
| 143 | ---------------------------------- |
| 144 | |
| 145 | Here are the contents of .../build-data/platforms/vpp.mk: |
| 146 | |
| 147 | :: |
| 148 | |
| 149 | MACHINE=$(shell uname -m) |
| 150 | |
| 151 | vpp_arch = native |
| 152 | ifeq ($(TARGET_PLATFORM),thunderx) |
| 153 | vpp_dpdk_target = arm64-thunderx-linuxapp-gcc |
| 154 | endif |
| 155 | vpp_native_tools = vppapigen |
| 156 | |
| 157 | vpp_uses_dpdk = yes |
| 158 | |
| 159 | # Uncoment to enable building unit tests |
| 160 | # vpp_enable_tests = yes |
| 161 | |
| 162 | vpp_root_packages = vpp vom japi |
| 163 | |
| 164 | # DPDK configuration parameters |
| 165 | # vpp_uses_dpdk_mlx4_pmd = yes |
| 166 | # vpp_uses_dpdk_mlx5_pmd = yes |
| 167 | # vpp_uses_external_dpdk = yes |
| 168 | # vpp_dpdk_inc_dir = /usr/include/dpdk |
| 169 | # vpp_dpdk_lib_dir = /usr/lib |
| 170 | # vpp_dpdk_shared_lib = yes |
| 171 | |
| 172 | # Use '--without-libnuma' for non-numa aware architecture |
| 173 | # Use '--enable-dlmalloc' to use dlmalloc instead of mheap |
| 174 | vpp_configure_args_vpp = --enable-dlmalloc |
| 175 | sample-plugin_configure_args_vpp = --enable-dlmalloc |
| 176 | |
| 177 | # load balancer plugin is not portable on 32 bit platform |
| 178 | ifeq ($(MACHINE),i686) |
| 179 | vpp_configure_args_vpp += --disable-lb-plugin |
| 180 | endif |
| 181 | |
| 182 | vpp_debug_TAG_CFLAGS = -g -O0 -DCLIB_DEBUG -DFORTIFY_SOURCE=2 \ |
| 183 | -fstack-protector-all -fPIC -Werror |
| 184 | vpp_debug_TAG_CXXFLAGS = -g -O0 -DCLIB_DEBUG -DFORTIFY_SOURCE=2 \ |
| 185 | -fstack-protector-all -fPIC -Werror |
| 186 | vpp_debug_TAG_LDFLAGS = -g -O0 -DCLIB_DEBUG -DFORTIFY_SOURCE=2 \ |
| 187 | -fstack-protector-all -fPIC -Werror |
| 188 | |
| 189 | vpp_TAG_CFLAGS = -g -O2 -DFORTIFY_SOURCE=2 -fstack-protector -fPIC -Werror |
| 190 | vpp_TAG_CXXFLAGS = -g -O2 -DFORTIFY_SOURCE=2 -fstack-protector -fPIC -Werror |
| 191 | vpp_TAG_LDFLAGS = -g -O2 -DFORTIFY_SOURCE=2 -fstack-protector -fPIC -Werror -pie -Wl,-z,now |
| 192 | |
| 193 | vpp_clang_TAG_CFLAGS = -g -O2 -DFORTIFY_SOURCE=2 -fstack-protector -fPIC -Werror |
| 194 | vpp_clang_TAG_LDFLAGS = -g -O2 -DFORTIFY_SOURCE=2 -fstack-protector -fPIC -Werror |
| 195 | |
| 196 | vpp_gcov_TAG_CFLAGS = -g -O0 -DCLIB_DEBUG -fPIC -Werror -fprofile-arcs -ftest-coverage |
| 197 | vpp_gcov_TAG_LDFLAGS = -g -O0 -DCLIB_DEBUG -fPIC -Werror -coverage |
| 198 | |
| 199 | vpp_coverity_TAG_CFLAGS = -g -O2 -fPIC -Werror -D__COVERITY__ |
| 200 | vpp_coverity_TAG_LDFLAGS = -g -O2 -fPIC -Werror -D__COVERITY__ |
| 201 | |
| 202 | Note the following variable settings: |
| 203 | |
| 204 | - The variable \_arch sets the CPU architecture used to build the |
| 205 | per-platform cross-compilation toolchain. With the exception of the |
| 206 | "native" architecture - used in our example - the vpp build system |
| 207 | produces cross-compiled binaries. |
| 208 | |
| 209 | - The variable \_native\_tools lists the required set of self-compiled |
| 210 | build tools. |
| 211 | |
| 212 | - The variable \_root\_packages lists the set of images to build when |
| 213 | specifying the target: make PLATFORM= TAG= [install-deb \| |
| 214 | install-rpm]. |
| 215 | |
| 216 | The TAG variable |
| 217 | ---------------- |
| 218 | |
| 219 | The TAG variable indirectly sets CFLAGS and LDFLAGS, as well as the |
| 220 | build and install directory names in the .../vpp/build-root directory. |
| 221 | See definitions above. |
| 222 | |
| 223 | Important targets build-root/Makefile |
| 224 | ------------------------------------- |
| 225 | |
| 226 | The main Makefile and the various makefile fragments implement the |
| 227 | following user-visible targets: |
| 228 | |
| 229 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 230 | | Target | ENV Variable Settings| Notes | |
| 231 | | | | | |
| 232 | +==================+======================+======================================================================================+ |
| 233 | | foo | bar | mumble | |
| 234 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 235 | | bootstrap-tools | none | Builds the set of native tools needed by the vpp build system to | |
| 236 | | | | build images. Example: vppapigen. In a full cross compilation case might include | |
| 237 | | | | include "make", "git", "find", and "tar | |
| 238 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 239 | | install-tools | PLATFORM | Builds the tool chain for the indicated <platform>. Not used in vpp builds | |
| 240 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 241 | | distclean | none | Roto-rooters everything in sight: toolchains, images, and so forth. | |
| 242 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 243 | | install-deb | PLATFORM and TAG | Build Debian packages comprising components listed in <platform>_root_packages, | |
| 244 | | | | using compile / link options defined by TAG. | |
| 245 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 246 | | install-rpm | PLATFORM and TAG | Build RPMs comprising components listed in <platform>_root_packages, | |
| 247 | | | | using compile / link options defined by TAG. | |
| 248 | +------------------+----------------------+--------------------------------------------------------------------------------------+ |
| 249 | |
| 250 | Additional build-root/Makefile environment variable settings |
| 251 | ------------------------------------------------------------ |
| 252 | |
| 253 | These variable settings may be of use: |
| 254 | |
| 255 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 256 | | ENV Variable | Notes | |
| 257 | +======================+======================+=====================================================================================+ |
| 258 | | BUILD_DEBUG=vx | Directs Makefile et al. to make a good-faith effort to show what's going on in excruciating detail. | |
| 259 | | | Use it as follows: "make ... BUILD_DEBUG=vx". Fairly effective in Makefile debug situations. | |
| 260 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 261 | | V=1 | print detailed cc / ld command lines. Useful for discovering if -DFOO=11 is in the command line or not | |
| 262 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 263 | | CC=mygcc | Override the configured C-compiler | |
| 264 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 265 | |
| 266 | .../build-root/config.site |
| 267 | -------------------------- |
| 268 | |
| 269 | The contents of .../build-root/config.site override individual autoconf / |
| 270 | automake default variable settings. Here are a few sample settings related to |
| 271 | building a full toolchain: |
| 272 | |
| 273 | :: |
| 274 | |
| 275 | # glibc needs these setting for cross compiling |
| 276 | libc_cv_forced_unwind=yes |
| 277 | libc_cv_c_cleanup=yes |
| 278 | libc_cv_ssp=no |
| 279 | |
| 280 | Determining the set of variables which need to be overridden, and the |
| 281 | override values is a matter of trial and error. It should be |
| 282 | unnecessary to modify this file for use with fd.io vpp. |
| 283 | |
| 284 | .../build-data/platforms.mk |
| 285 | --------------------------- |
| 286 | |
| 287 | Each repo group includes the platforms.mk file, which is included by |
| 288 | the main Makefile. The vpp/build-data/platforms.mk file is not terribly |
| 289 | complex. As of this writing, .../build-data/platforms.mk file accomplishes two |
| 290 | tasks. |
| 291 | |
| 292 | First, it includes vpp/build-data/platforms/\*.mk: |
| 293 | |
| 294 | :: |
| 295 | |
| 296 | # Pick up per-platform makefile fragments |
| 297 | $(foreach d,$(SOURCE_PATH_BUILD_DATA_DIRS), \ |
| 298 | $(eval -include $(d)/platforms/*.mk)) |
| 299 | |
| 300 | This collects the set of platform definition makefile fragments, as discussed above. |
| 301 | |
| 302 | Second, platforms.mk implements the user-visible "install-deb" target. |
| 303 | |
| 304 | .../build-data/packages/\*.mk |
| 305 | ----------------------------- |
| 306 | |
| 307 | Each component needs a makefile fragment in order for the build system |
| 308 | to recognize it. The per-component makefile fragments vary |
| 309 | considerably in complexity. For a component built with GNU autoconf / |
| 310 | automake which does not depend on other components, the make fragment |
| 311 | can be empty. See .../build-data/packages/vpp.mk for an uncomplicated |
| 312 | but fully realistic example. |
| 313 | |
| 314 | Here are some of the important variable settings in per-component makefile fragments: |
| 315 | |
| 316 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 317 | | Variable | Notes | |
| 318 | +======================+======================+=====================================================================================+ |
| 319 | | xxx_configure_depend | Lists the set of component build dependencies for the xxx component. In plain English: don't try to | |
| 320 | | | configure this component until you've successfully built the indicated targets. Almost always, | |
| 321 | | | xxx_configure_depend will list a set of "yyy-install" targets. Note the pattern: | |
| 322 | | | "variable names contain underscores, make target names contain hyphens" | |
| 323 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 324 | | xxx_configure_args | (optional) Lists any additional arguments to pass to the xxx component "configure" script. | |
| 325 | | | The main Makefile %-configure rule adds the required settings for --libdir, --prefix, and | |
| 326 | | | --host (when cross-compiling) | |
| 327 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 328 | | xxx_CPPFLAGS | Adds -I stanzas to CPPFLAGS for components upon which xxx depends. | |
| 329 | | | Almost invariably "xxx_CPPFLAGS = $(call installed_includes_fn, dep1 dep2 dep3)", where dep1, dep2, and | |
| 330 | | | dep3 are listed in xxx_configure_depend. It is bad practice to set "-g -O3" here. Those settings | |
| 331 | | | belong in a TAG. | |
| 332 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 333 | | xxx_LDFLAGS | Adds -Wl,-rpath -Wl,depN stanzas to LDFLAGS for components upon which xxx depends. | |
| 334 | | | Almost invariably "xxx_LDFLAGS = $(call installed_lib_fn, dep1 dep2 dep3)", where dep1, dep2, and | |
| 335 | | | dep3 are listed in xxx_configure_depend. It is bad manners to set "-liberty-or-death" here. | |
| 336 | | | Those settings belong in Makefile.am. | |
| 337 | +----------------------+------------------------------------------------------------------------------------------------------------+ |
| 338 | |
| 339 | When dealing with "irritating" components built with raw Makefiles |
| 340 | which only work when building in the source tree, we use a specific |
| 341 | strategy in the xxx.mk file. |
| 342 | |
| 343 | The strategy is simple for those components: We copy the source tree |
| 344 | into .../vpp/build-root/build-xxx. This works, but completely defeats |
| 345 | dependency processing. This strategy is acceptable only for 3rd party |
| 346 | software which won't need extensive (or preferably any) modifications. |
| 347 | |
| 348 | Take a look at .../vpp/build-data/packages/dpdk.mk. When invoked, the |
| 349 | dpdk_configure variable copies source code into $(PACKAGE_BUILD_DIR), |
| 350 | and performs the BSD equivalent of "autoreconf -i -f" to configure the |
| 351 | build area. The rest of the file is similar: a bunch of hand-rolled |
| 352 | glue code which manages to make the dpdk act like a good vpp build |
| 353 | citizen even though it is not. |