1246149Ssjgmk-files 2246149Ssjg******** 3246149Ssjg 4246149SsjgThe term ``mk-files`` refers to a collection of ``*.mk`` files. 5246149Ssjg 6246149SsjgYou need bmake_ or a *recent* NetBSD_ make. 7246149SsjgIf in doubt use bmake_. 8246149Ssjg 9246149SsjgIntroduction 10246149Ssjg============ 11246149Ssjg 12246149SsjgMany years ago, when building large software projects, I used GNU make 13246149Ssjg(or my own patched version of it), and had developed a set of macros 14246149Ssjgto simplify developing complex build trees. 15246149Ssjg 16246149SsjgSince the early 90's my main development machines, run BSD 17246149Ssjg(NetBSD_ to be precise), and the BSD source tree is good example of a 18246149Ssjglarge software project. It quickly became clear that 19246149Ssjg``/usr/share/mk/*.mk`` were a great model, but were quite tightly 20246149Ssjglinked to building the BSD tree. 21246149Ssjg 22246149SsjgMuch as I liked using NetBSD, my customers were more likely to be 23246149Ssjgusing SunOS, HP-UX etc, so I started on bmake_ and a portable collection 24246149Ssjgof mk-files (mk.tar.gz_). NetBSD provided much of the original structure. 25246149Ssjg 26246149SsjgSince then I've added a lot of features to NetBSD's make and hence to 27246149Ssjgbmake which is kept closely in sync. The mk-files however have 28246149Ssjgdiverged quite a bit, though ideas are still picked up from NetBSD. 29246149Ssjg 30246149SsjgBasics 31246149Ssjg------ 32246149Ssjg 33246149SsjgThe BSD build model is very simple. A directory produces one 34246149Ssjgcomponent, which is generally either a library or a program. 35246149SsjgLibrary makefiles include ``lib.mk`` and programs include ``prog.mk`` 36246149Ssjgand they *do the right thing*. 37246149Ssjg 38246149SsjgA simple library makefile might look like:: 39246149Ssjg 40246149Ssjg LIB = sig 41246149Ssjg 42246149Ssjg SRCS = \ 43246149Ssjg sigaction.c \ 44246149Ssjg sigcompat.c \ 45246149Ssjg sighdl.c 46246149Ssjg 47246149Ssjg .include <lib.mk> 48246149Ssjg 49246149Ssjga simple program makefile:: 50246149Ssjg 51246149Ssjg PROG = cat 52246149Ssjg 53246149Ssjg SRCS = cat.c 54246149Ssjg 55246149Ssjg .include <prog.mk> 56246149Ssjg 57246149Ssjgin such cases even the ``SRCS`` line is unnecessary as ``prog.mk`` 58246149Ssjgwill default it to ``${PROG}.c``. 59246149Ssjg 60246149SsjgIt is the sensible use of defaults and the plethora of macro modifiers 61246149Ssjgprovided by bmake_ that allow simple makefiles such as the above 62246149Ssjg*just work* on many different systems. 63246149Ssjg 64246149Ssjg 65246149Ssjgmk-files 66246149Ssjg======== 67246149Ssjg 68246149SsjgThis section provides a brief description of some of the ``*.mk`` 69246149Ssjgfiles. 70246149Ssjg 71246149Ssjgsys.mk 72246149Ssjg------ 73246149Ssjg 74246149SsjgWhen bmake starts, it looks for ``sys.mk`` and reads it before doing 75246149Ssjganything else. Thus, this is the place to setup the environment for 76246149Ssjgeveryone else. 77246149Ssjg 78246149SsjgIn this distribution, sys.mk avoids doing anything platform dependent. 79246149SsjgIt is quite short, and includes a number of other files (which may or 80246149Ssjgmay not exists) 81246149Ssjg 82246149Ssjgsys.env.mk 83246149Ssjg If it exists, is expected to do things like conditioning the 84246149Ssjg environment. Since it will only be included by the initial 85246149Ssjg instance of bmake, it should ``.export`` anything that 86246149Ssjg sub-makes might need. 87246149Ssjg 88246149Ssjgexamples/sys.clean-env.mk 89246149Ssjg An example of how to clean the environment. 90246149Ssjg See the file for all the details:: 91246149Ssjg 92246149Ssjg .if ${MAKE_VERSION} >= 20100606 && ${.MAKE.LEVEL} == 0 93246149Ssjg # we save any env var that starts with these 94246149Ssjg MAKE_SAVE_ENV_PREFIX += SB MK MAKE MACHINE NEED_ CCACHE DISTCC USE_ SSH 95246149Ssjg MAKE_SAVE_ENV_VARS += \ 96246149Ssjg PATH HOME USER LOGNAME \ 97246149Ssjg SRCTOP OBJTOP OBJROOT \ 98246149Ssjg ${_env_vars} 99246149Ssjg 100246149Ssjg _env_vars != env | egrep '^(${MAKE_SAVE_ENV_PREFIX:ts|})' | sed 's,=.*,,'; echo 101246149Ssjg _export_list = 102246149Ssjg .for v in ${MAKE_SAVE_ENV_VARS:O:u} 103246149Ssjg .if !empty($v) 104246149Ssjg _export_list += $v 105246149Ssjg $v := ${$v} 106246149Ssjg .endif 107246149Ssjg .endfor 108246149Ssjg # now clobber the environment 109246149Ssjg .unexport-env 110246149Ssjg 111246149Ssjg # list of vars that we handle specially below 112246149Ssjg _tricky_env_vars = MAKEOBJDIR 113246149Ssjg # export our selection - sans tricky ones 114246149Ssjg .export ${_export_list:${_tricky_env_vars:${M_ListToSkip}}} 115246149Ssjg 116246149Ssjg # this next bit may need tweaking 117246149Ssjg .if defined(MAKEOBJDIR) 118246149Ssjg srctop := ${SRCTOP:U${SB_SRC:U${SB}/src}} 119246149Ssjg objroot := ${OBJROOT:U${SB_OBJROOT:U${SB}/${SB_OBJPREFIX}}} 120246149Ssjg # we'll take care of MACHINE below 121246149Ssjg objtop := ${OBJTOP:U${objroot}${MACHINE}} 122246149Ssjg .if !empty(objtop) 123246149Ssjg # we would normally want something like (/bin/sh): 124246149Ssjg # MAKEOBJDIR="\${.CURDIR:S,${SRCTOP},${OBJROOT}\${MACHINE},}" 125246149Ssjg # the $$ below is how we achieve the same result here. 126246149Ssjg # since everything saved from the environment above 127246149Ssjg # has run through := we need to compensate for ${MACHINE} 128246149Ssjg MAKEOBJDIR = $${.CURDIR:S,${srctop},${objtop:S,${MACHINE},\${MACHINE},},} 129246149Ssjg 130246149Ssjg # export these as-is, and do not track... 131246149Ssjg .export-env ${_tricky_env_vars} 132246149Ssjg # now evaluate for ourselves 133246149Ssjg .for v in ${_tricky_env_vars} 134246149Ssjg $v := ${$v} 135246149Ssjg .endfor 136246149Ssjg 137246149Ssjg .endif 138246149Ssjg .endif 139246149Ssjg .endif 140246149Ssjg 141246149Ssjg 142246149Ssjghost-target.mk 143246149Ssjg Is used to set macros like ``HOST_TARGET``, ``HOST_OS`` and 144246149Ssjg ``host_os`` which are used to find the next step. 145246149Ssjg 146246149Ssjgsys/\*.mk 147246149Ssjg Platform specific additions, such as ``Darwin.mk`` or ``SunOS.mk`` 148246149Ssjg set things like ``HOST_LIBEXT = .dylib`` for Darwin or 149246149Ssjg ``SHLIB_FULLVERSION = ${SHLIB_MAJOR}`` for SunOS 5. 150246149Ssjg If there is no OS specific file, ``sys/Generic.mk`` is used. 151246149Ssjg 152246149Ssjglocal.sys.mk 153246149Ssjg Any ``local.*.mk`` file is not part of the distribution. 154246149Ssjg This provides a hook for sites to do extra setup without 155246149Ssjg having to edit the distributed files. 156246149Ssjg 157246149Ssjg 158246149SsjgThe above arrangement makes it easy for the mk files to be part of a 159246149Ssjgsrc tree on an NFS volume and to allow building on multiple platforms. 160246149Ssjg 161246149Ssjglib.mk 162246149Ssjg------ 163246149Ssjg 164246149SsjgThis file is used to build a number of different libraries from the 165246149Ssjgsame SRCS. 166246149Ssjg 167246149Ssjglib${LIB}.a 168246149Ssjg An archive lib of ``.o`` files, this is the default 169246149Ssjg 170246149Ssjglib${LIB}_p.a 171246149Ssjg A profiled lib of ``.po`` files. 172246149Ssjg Still an archive lib, but all the objects are built with 173246149Ssjg profiling in mind - hence the different extension. 174246149Ssjg It is skipped if ``MKPROFILE`` is "no". 175246149Ssjg 176246149Ssjglib${LIB}_pic.a 177246149Ssjg An archive of ``.so`` objects compiled for relocation. 178246149Ssjg On NetBSD this is the input to ``lib${LIB}.${LD_so}``, it is 179246149Ssjg skipped if ``MKPICLIB`` is "no". 180246149Ssjg 181246149Ssjglib${LIB}.${LD_so} 182246149Ssjg A shared library. The value of ``LD_so`` is very platform 183246149Ssjg specific. For example:: 184246149Ssjg 185246149Ssjg # SunOS 5 and most other ELF systems 186246149Ssjg libsslfd.so.1 187246149Ssjg 188246149Ssjg # Darwin 189246149Ssjg libsslfd.1.dylib 190246149Ssjg 191246149Ssjg This library will only be built if ``SHLIB_MAJOR`` has 192246149Ssjg a value, and ``MKPIC`` is not set to "no". 193246149Ssjg 194246149SsjgThere is a lot of platform specific tweaking in ``lib.mk``, largely the 195246149Ssjgresult of the original distributions trying to avoid interfering with 196246149Ssjgthe system's ``sys.mk``. 197246149Ssjg 198246149Ssjglibnames.mk 199246149Ssjg----------- 200246149Ssjg 201246149SsjgThis is included by both ``prog.mk`` and ``lib.mk`` and tries to 202246149Ssjginclude ``*.libnames.mk`` of which: 203246149Ssjg 204246149Ssjglocal.libnames.mk 205246149Ssjg does not exist unless you create it. It is a handy way for you 206246149Ssjg to customize without touching the distributed files. 207246149Ssjg For example, on a test machine I needed to build openssl but 208246149Ssjg not install it, so put the following in ``local.libnames.mk``:: 209246149Ssjg 210246149Ssjg .if ${host_os} == "sunos" 211246149Ssjg LIBCRYPTO = ${OBJTOP}/openssl/lib/crypto/libcrypto${DLIBEXT} 212246149Ssjg LIBSSL = ${OBJTOP}/openssl/lib/ssl/libssl${DLIBEXT} 213246149Ssjg INCLUDES_libcrypto = -I${OBJ_libcrypto} 214246149Ssjg .endif 215246149Ssjg 216246149Ssjg The makefile created an openssl dir in ``${OBJ_libcrypto}`` to 217246149Ssjg gather all the headers. dpadd.mk_ did the rest. 218246149Ssjg 219246149Ssjgsjg.libnames.mk 220246149Ssjg not part of the mk-files distribution. 221246149Ssjg 222246149Ssjghost.libnames.mk 223246149Ssjg contains logic to find any libs named in ``HOST_LIBS`` in 224246149Ssjg ``HOST_LIBDIRS``. 225246149Ssjg 226246149SsjgEach file above gets an opportunity to define things like:: 227246149Ssjg 228246149Ssjg LIBSSLFD ?= ${OBJTOP}/ssl/lib/sslfd/libsslfd${DLIBEXT} 229246149Ssjg INCLUDES_libsslfd = -I${SRC_libsslfd}/h -I${OBJ_libslfd} 230246149Ssjg 231246149Ssjgthese are used by dpadd.mk_ and will be explained below. 232246149Ssjg 233246149Ssjgdpadd.mk 234246149Ssjg-------- 235246149Ssjg 236246149SsjgThis file looks like line noise, and is best considered read-only. 237246149SsjgHowever it provides some very useful functionality, which simplifies the build. 238246149Ssjg 239246149SsjgMakefiles can use the LIB* macros defined via libnames.mk_ or anywhere 240246149Ssjgelse in various ways:: 241246149Ssjg 242246149Ssjg # indicate that we need to include headers from LIBCRYPTO 243246149Ssjg # this would result in ${INCLUDES_libcrypto} being added to CFLAGS. 244246149Ssjg SRC_LIBS += ${LIBCRYPTO} 245246149Ssjg 246246149Ssjg # indicate that libsslfd must be built already. 247246149Ssjg # it also has the same effect as SRC_LIBS 248246149Ssjg DPADD += ${LIBSSLFD} 249246149Ssjg 250246149Ssjg # indicate that not only must libsslfd be built, 251246149Ssjg # but that we need to link with it. 252246149Ssjg # this is almost exactly equivalent to 253246149Ssjg # DPADD += ${LIBSSLFD} 254246149Ssjg # LDADD += -L${LIBSSLFD:H} -lsslfd 255246149Ssjg # and mostly serves to ensure that DPADD and LDADD are in sync. 256246149Ssjg DPLIBS += ${LIBSSLFD} 257246149Ssjg 258246149SsjgAny library (referenced by its full path) in any of the above, is 259246149Ssjgadded to ``DPMAGIC_LIBS`` with the following results, for each lib *foo*. 260246149Ssjg 261246149SsjgSRC_libfoo 262246149Ssjg Is set to indicate where the src for libfoo is. 263246149Ssjg By default it is derived from ``LIBFOO`` by replacing 264246149Ssjg ``${OBJTOP}`` with ``${SRCTOP}``. 265246149Ssjg 266246149SsjgOBJ_libfoo 267246149Ssjg Not very exciting, is just the dir where libfoo lives. 268246149Ssjg 269246149SsjgINCLUDES_libfoo 270246149Ssjg What to add to ``CFLAGS`` to find the public headers. 271246149Ssjg The default varies. If ``${SRC_libfoo}/h`` exists, it is assumed 272246149Ssjg to be the home of all public headers and thus the default is 273246149Ssjg ``-I${SRC_libfoo}/h`` 274246149Ssjg 275246149Ssjg Otherwise we make no assumptions and the default is 276246149Ssjg ``-I${SRC_libfoo} -I${OBJ_libfoo}`` 277246149Ssjg 278246149SsjgLDADD_libfoo 279246149Ssjg This only applies to libs reference via ``DPLIBS``. 280246149Ssjg The default is ``-lfoo``, ``LDADD_*`` provides a hook to 281246149Ssjg instantiate other linker flags at the appropriate point 282246149Ssjg without losing the benfits of ``DPLIBS``. 283246149Ssjg 284246149Ssjgprog.mk 285246149Ssjg------- 286246149Ssjg 287246149SsjgCompiles the specified SRCS and links them and the nominated libraries 288246149Ssjginto a program. Prog makefiles usually need to list the libraries 289246149Ssjgthat need to be linked. We prefer use of ``DPLIBS`` but the more 290246149Ssjgtraditional ``DPADD`` and ``LDADD`` work just as well. 291246149SsjgThat is:: 292246149Ssjg 293246149Ssjg DPLIBS += ${LIBCRYPTO} 294246149Ssjg 295246149Ssjgis equivalent to:: 296246149Ssjg 297246149Ssjg DPADD += ${LIBCRYPTO} 298246149Ssjg LDADD += -lcrypto 299246149Ssjg 300246149Ssjgobj.mk 301246149Ssjg------ 302246149Ssjg 303246149SsjgOne of the cool aspects of BSD make, is its support for separating 304246149Ssjgobject files from the src tree. This is also the source of much 305246149Ssjgconfusion to some. 306246149Ssjg 307246149SsjgTraditionally one had to do a separate ``make obj`` pass through the 308246149Ssjgtree. If ``MKOBJDIRS`` is "auto", we include auto.obj.mk_. 309246149Ssjg 310246149Ssjgauto.obj.mk 311246149Ssjg----------- 312246149Ssjg 313246149SsjgThis leverages the ``.OBJDIR`` target introduced some years ago to 314246149SsjgNetBSD make, to automatically create the desired object dir. 315246149Ssjg 316246149Ssjgsubdir.mk 317246149Ssjg--------- 318246149Ssjg 319246149SsjgThis is the traditional means of walking the tree. A makefile sets 320246149Ssjg``SUBDIR`` to the list of sub-dirs to visit. 321246149Ssjg 322246149SsjgIf ``SUBDIR_MUST_EXIST`` is set, missing directories cause an error, 323246149Ssjgotherwise a warning is issued. If you don't even want the warning, 324246149Ssjgset ``MISSING_DIR=continue``. 325246149Ssjg 326246149SsjgTraditionally, ``subdir.mk`` prints clue as it visits each subdir:: 327246149Ssjg 328246149Ssjg ===> ssl 329246149Ssjg ===> ssl/lib 330246149Ssjg ===> ssl/lib/sslfd 331246149Ssjg 332246149Ssjgyou can suppress that - or enhance it by setting ``ECHO_DIR``:: 333246149Ssjg 334246149Ssjg # suppress subdir noise 335246149Ssjg ECHO_DIR=: 336246149Ssjg # print time stamps 337246149Ssjg ECHO_DIR=echo @ `date "+%s [%Y-%m-%d %T] "` 338246149Ssjg 339246149Ssjglinks.mk 340246149Ssjg-------- 341246149Ssjg 342246149SsjgProvides rules for processing lists of ``LINKS`` and ``SYMLINKS``. 343246149SsjgEach is expected to be a list of ``link`` and ``target`` pairs 344246149Ssjg(``link`` -> ``target``). 345246149Ssjg 346246149SsjgThe logic is generally in a ``_*_SCRIPT`` which is referenced in a 347246149Ssjg``_*_USE`` (``.USE``) target. 348246149Ssjg 349246149SsjgThe ``_BUILD_*`` forms are identical, but do not use ``${DESTDIR}`` 350246149Ssjgand so are useful for creating symlinks during the build phase. 351246149SsjgFor example:: 352246149Ssjg 353246149Ssjg SYMLINKS += ${.CURDIR}/${MACHINE_ARCH}/include machine 354246149Ssjg header_links: _BUILD_SYMLINKS_USE 355246149Ssjg 356246149Ssjg md.o: header_links 357246149Ssjg 358246149Ssjgwould create a symlink called ``machine`` in ``${.OBJDIR}`` pointing to 359246149Ssjg``${.CURDIR}/${MACHINE_ARCH}/include`` before compiling ``md.o`` 360246149Ssjg 361246149Ssjg 362246149Ssjgautoconf.mk 363246149Ssjg----------- 364246149Ssjg 365246149SsjgDeals with running (or generating) GNU autoconf ``configure`` scripts. 366246149Ssjg 367246149Ssjgdep.mk 368246149Ssjg------ 369246149Ssjg 370246149SsjgDeals with collecting dependencies. Another useful feature of BSD 371246149Ssjgmake is the separation of this sort of information into a ``.depend`` 372246149Ssjgfile. ``MKDEP`` needs to point to a suitable tool (like mkdeps.sh_) 373246149Ssjg 374246149SsjgIf ``USE_AUTODEP_MK`` is "yes" includes autodep.mk_ 375246149Ssjg 376246149Ssjgautodep.mk 377246149Ssjg---------- 378246149Ssjg 379246149SsjgLeverages the ``-MD`` feature of recent GCC to collect dependency 380246149Ssjginformation as a side effect of compilation. With this GCC puts 381246149Ssjgdependency info into a ``.d`` file. 382246149Ssjg 383246149SsjgUnfortunately GCC bases the name of the ``.d`` file on the name of the 384246149Ssjginput rather than the output file, which causes problems when the same 385246149Ssjgsource is compiled different ways. The latest GCC supports ``-MF`` to 386246149Ssjgname the ``.d`` file and ``-MT`` to control the name to put as the 387246149Ssjgdependent. 388246149Ssjg 389246149SsjgRecent bmake allows dependencies for the ``.END`` target (run at the 390246149Ssjgend if everything was successful), and ``autodep.mk`` uses this to 391246149Ssjgpost process the ``.d`` files into ``.depend``. 392246149Ssjg 393246149Ssjgauto.dep.mk 394246149Ssjg----------- 395246149Ssjg 396246149SsjgA much simpler implementation than autodep.mk_ it uses 397246149Ssjg``-MF ${.TARGET:T}.d`` 398246149Ssjgto avoid possible conflicts during parallel builds. 399246149SsjgThis precludes the use of suffix rules to drive ``make depend``, so 400246149Ssjgdep.mk_ handles that if specifically requested. 401246149Ssjg 402246149Ssjgown.mk 403246149Ssjg------ 404246149Ssjg 405246149SsjgNormally included by ``init.mk`` (included by ``lib.mk`` and 406246149Ssjg``prog.mk`` etc), sets macros for default ownership etc. 407246149Ssjg 408246149SsjgIt includes ``${MAKECONF}`` if it is defined and exists. 409246149Ssjg 410246149Ssjgman.mk 411246149Ssjg------ 412246149Ssjg 413246149SsjgDeals with man pages. 414246149Ssjg 415246149Ssjgwarnings.mk 416246149Ssjg----------- 417246149Ssjg 418246149SsjgThis provides a means of fine grained control over warnings on a per 419246149Ssjg``${MACHINE}`` or even file basis. 420246149Ssjg 421246149SsjgA makefile sets ``WARNINGS_SET`` to name a list of warnings 422246149Ssjgand individual ``W_*`` macros can be used to tweak them. 423246149SsjgFor example:: 424246149Ssjg 425246149Ssjg WARNINGS_SET = HIGH 426246149Ssjg W_unused_sparc = -Wno-unused 427246149Ssjg 428246149Ssjgwould add all the warnings in ``${HIGH_WARNINGS}`` to CFLAGS, but 429246149Ssjgon sparc, ``-Wno-unused`` would replace ``-Wunused``. 430246149Ssjg 431246149SsjgYou should never need to edit ``warnings.mk``, it will include 432246149Ssjg``warnings-sets.mk`` if it exists and you use that to make any local 433246149Ssjgcustomizations. 434246149Ssjg 435281812Ssjgrst2htm.mk 436281812Ssjg---------- 437281812Ssjg 438281812SsjgLogic to simplify generating HTML (and PDF) documents from ReStructuredText. 439281812Ssjg 440281812Ssjgcython.mk 441281812Ssjg--------- 442281812Ssjg 443281812SsjgLogic to build Python C interface modules using Cython_ 444281812Ssjg 445281812Ssjg.. _Cython: http://www.cython.org/ 446281812Ssjg 447246149SsjgMeta mode 448246149Ssjg========= 449246149Ssjg 450246149SsjgThe 20110505 and later versions of ``mk-files`` include a number of 451281812Ssjgmakefiles contributed by Juniper Networks, Inc. 452281812SsjgThese allow the latest version of bmake_ to run in `meta mode`_ 453281812Ssjgsee `dirdeps.mk`_ 454246149Ssjg 455281812Ssjg.. _`dirdeps.mk`: /help/sjg/dirdeps.htm 456246149Ssjg.. _`meta mode`: bmake-meta-mode.htm 457246149Ssjg 458246149SsjgInstall 459246149Ssjg======= 460246149Ssjg 461246149SsjgYou can use the content of mk.tar.gz_ without installing at all. 462246149Ssjg 463246149SsjgThe script ``install-mk`` takes care of copying ``*.mk`` into a 464246149Ssjgdestination directory, and unless told not to, create ``bsd.*.mk`` links 465246149Ssjgfor ``lib.mk`` etc. 466246149Ssjg 467246149SsjgIf you just want to create the ``bsd.*.mk`` links in the directory 468246149Ssjgwhere you unpacked the tar file, you can:: 469246149Ssjg 470246149Ssjg ./mk/install-mk ./mk 471246149Ssjg 472246149Ssjg------ 473246149Ssjg 474246149Ssjg.. _bmake: bmake.htm 475246149Ssjg.. _NetBSD: http://www.netbsd.org/ 476246149Ssjg.. _mkdeps.sh: http://www.crufty.net/ftp/pub/sjg/mkdeps.sh 477246149Ssjg.. _mk.tar.gz: http://www.crufty.net/ftp/pub/sjg/mk.tar.gz 478246149Ssjg 479246149Ssjg:Author: sjg@crufty.net 480281812Ssjg:Revision: $Id: mk-files.txt,v 1.16 2014/09/05 04:41:16 sjg Exp $ 481246149Ssjg:Copyright: Crufty.NET 482