MK-CONFIGURE(7)

✨ NAME ✨

MK-CONFIGURE(7) β€” hi bestie, this is the page for mk-configure, the lightweight replacement for GNU autotools. That's the whole name section, short and iconic. πŸŽ€


🌸 DESCRIPTION 🌸

Okay so picture this: mk-configure is a collection of include files for bmake (that's the portable version of NetBSD make, iykyk) plus a whole bunch of executables. Its whole personality? Making crossplatform development and software building so much simpler for you. πŸ’–

There are only a few top-level makefiles, and they are: mkc.init.mk, mkc.mk, mkc.configure.mk, mkc.minitest.mk. Everything else (the mkc_imp.*.mk files) gets included implicitely. Do not use mkc_imp.*.mk files directly! Like, genuinely don't. If you do, I cannot guarantee backward compatibility. πŸ’€

mkc.configure.mk is included automatically by mkc.mk, but can be included explicitely. mkc.minitest.mk provides a trivial support for regression tests and should be included explicitely.

Usually mk-c makefiles consist of variables assignments and inclusion of mkc.mk in the and. ✨

You can also use mkc.prog.mk, mkc.lib.mk, mkc.files.mk, mkc.subdir.mk and mkc.subprj.mk instead of mkc.mk. Here's the tea on how the latter picks: it activates mkc.lib.mk if variable LIB is set, mkc.prog.mk if variables PROG or PROGS are set, mkc.subprj.mk if variable SUBPRJ is set, mkc.subdir.mk if variable SUBDIR is set, and mkc.files.mk otherwise.

To get system-wide configuration parameters, mkc.init.mk loads "${MAKECONF}" file if it exists. Otherwise, it loads /etc/mkcmake.conf if it exists. If neither ${MAKECONF} nor /etc/mkcmake.conf exist, it tries to load /etc/mk.conf file. If "${SRCTOP}/Makefile.common" file exists it is also included by all subprojects. Unless SRCTOP variable is set, "../Makefile.inc" is also included if exists. These files may define any of the variables described below. Compiler-specific defaults are also loaded from "~/.mkcmake" or system directories. This compiler-specific defaults are determined at build time or with the help of mkc_compiler_settings utility. 🧚

Below in square brackets the default value for variables are specified. In triangle brackets β€” the typical way of use, where:

  • I means "Initialized by mk-configure"
  • Iu means "Initialized by mk-configure but may be overriden by user"
  • Im means "Initialized by mk-configure but may be set in Makefile"
  • U means "Usually set by user"
  • M means "May be set or changed in project's Makefile"
  • Mu means "May be set in project's Makefile but may be initialized or overriden by user"

Variable MKCMAKE is always 1 in mkcmake. No cap. 🫢


🎯 Targets

Mk-configure provides the following targets:

  • all β€” build everything. πŸ—οΈ
  • clean β€” clean temporary files and directories with the help of ${CLEANFILES_CMD} and ${CLEANDIRS_CMD} commands.
  • cleandir β€” remove all of the files removed by the target clean, as well as cache files created by mkc.configure.mk.
  • installdirs β€” create target directories.
  • install β€” install programs, libraries, files, include files, manual pages etc. to the target directories with the help of ${INSTALL} program.
  • uninstall β€” remove installed files with the help of ${UNINSTALL} command.
  • configure β€” check for MKC_ERR_MSG variable and fails if it set printing an error message
  • depend β€” create .depend_${.CURDIR:T} file containing list of dependencies (see mkdep(1)).
  • filelist β€” output a list of destination files of the project, one per line, e.g.
/usr/local/bin/hello
/usr/local/man/man1/hello.1
  • obj β€” if MKOBJDIR is "yes", creates object directories (${.OBJDIR}) according to MAKEOBJDIR and MAKEOBJPREFIX variables. Current umask is used for this.
  • mkgen β€” See mkc_imp.foreign_autotools.mk.
  • bin_tar, bin_targz, bin_tarbz2, bin_zip, bin_deb β€” build software, install it to a temporary directory (using DESTDIR) and create .tar/.tar.gz/.tar.bz2/.zip/.deb archive containing all installed files. The target bin_deb expects debian control files in DEBIAN subdirectory, see examples/files for the sample.
NOTE: Commands associated with targets all, install, clean, cleandir, depend, test, installdirs, uninstall, configure and filelist in Makefile override the standard behaviour.
NOTE: All targets in this list have pre_*, do_* and post_* counterparts. See ALLTARGETS for details.

🧚 mkc.init.mk

This file is included by mkc.mk and mkc.configure.mk automatically but can be used by users directly. mkc.init.mk uses the following variables. 🌈

  • AFLAGS β€” Options to ${CC} when compiling or linking .s or .S assembly source files. []
  • AR β€” Create, modify, and extract from archives. <Iu> [ar]
  • ARFLAGS β€” Options to ${AR}. <Iu> [rl]
  • AS β€” Assembler. <Iu> [as]
  • BINDIR β€” Target directory for utilities. <Iu Mu> [${PREFIX}/bin]
  • BMAKE_REQD β€” Minimal required version of bmake. If it is older, mkcmake exits with error. <Im>
  • BZIP2 β€” bzip2 copression tool. <Iu> [bzip2]
  • CC β€” C compiler. <Iu> [cc]
  • CC_PREFIX β€” Prefix command for ${CC}, for example, distcc or ccache. <Iu> []
  • CC_TYPE β€” C compiler type. This variable is set by mk-configure and can be overriden by user. It can get the following values:
    • gcc β€” GNU C/C++ compiler
    • pcc β€” Portable C compiler
    • icc β€” Intel C/C++ compiler
    • msc β€” Microsoft C/C++ compiler
    • armcc β€” ARM C/C++ compiler
    • hpc β€” HP-UX C/C++ compiler
    • sunpro β€” SUNWspro C/C++ compiler
    • ibmc β€” IBM C/C++ compiler (Visual Age for C/C++?)
    • bcc β€” Borland C/C++ compiler
    • watcom β€” Watcom C/C++ compiler
    • como β€” COMO C/C++ compiler
    • decc β€” DEC C
    • mipspro β€” MIPSpro C compiler

<Iu> [no]

  • CC_VERSION β€” C compiler version. <I>
  • CCSTD β€” Add C language standard command line option to the compiler. Supported options: c89, gnu89 (C89 with GNU extensions), c99, gnu99 (C99 with GNU extensions), c11, gnu11 (C89 with GNU extensions), c17, gnu17 (C17 with GNU extensions). If compiler is not known for mk-configure or does not support appropriate option, no additional options are applied. <M> []
  • CFLAGS β€” Additional flags to the compiler when creating C objects. <IM>
  • CFLAGS0 β€” The same as CFLAGS but CFLAGS0 is passed to the compiler before CFLAGS. Normally, CFLAGS0 should be modified in makefiles and should not be set from environment by user. <M>
  • CFLAGS.check β€” Same as CFLAGS but every option is checked whether it is a valid one for C compiler. Double underline in the flag is considered as a single space character. <M> [unset]
  • CFLAGS.dflt, CXXFLAGS.dflt β€” Additional flags passed to C or C++ compilers. <Iu>
  • CFLAGS.pic, CXXFLAGS.pic β€” Options for C and C++ compilers for generating position independent code. On some platforms it makes sense to override these variables (initialized by mk-configure) for better performance, for example, one may use -fpic instead of -fPIC with GNU C/C++ compilers. See SHLIB_MAJOR, MKPIE etc. variables for more information. <Iu>
  • CFLAGS.pie, CXXFLAGS.pie β€” Options for C and C++ compilers for generating position independent executables. On some platforms it makes sense to override these variables (initialized by mk-configure) for better performance, for example, one may use -fpic instead of -fPIC with GNU C/C++ compilers. See MKPIE variable for more information. <Iu>
  • CFLAGS.ssp, CXXFLAGS.ssp β€” Options for C and C++ compilers for generating stack protection code. See USE_SSP variable for more information. <Iu>
  • CFLAGS.warns.<warn-level>, CXXFLAGS.warns.<warn-level> β€” These variables are set by mk-configure and enable warnings for C or C++ compilers according to warning level (WARNS). <Iu>
  • CFLAGS_<project> β€” Similar to CFLAGS but for project ${PROJECTNAME}. <U>
  • CFLAGS_<source> β€” Similar to CFLAGS but for the specified source file. Basename of the source file is used. <Mu>
  • CLEANDIRS_CMD β€” Command for removing directories used by targets "clean" and "cleandir". <Iu> [${RM} -rf]
  • CLEANFILES_CMD β€” Command for removing files used by targets "clean" and "cleandir". <Iu> [${RM} -f]
  • COPTS β€” Additional flags to the compiler when creating C objects. <U>
  • COPTS_<project> β€” Similar to COPTS but for project ${PROJECTNAME}. <U>
  • CPP β€” C Pre-Processor. <Iu> [cpp]
  • CPPFLAGS β€” Additional flags to the C/C++ pre-processor. <Iu>
  • CPPFLAGS0 β€” The same as CPPFLAGS but CPPFLAGS0 is passed to the compiler before CPPFLAGS. Normally, CPPFLAGS0 should be modified in makefiles and should not be set from environment by user. <M>
  • CPPFLAGS_<project> β€” Similar to CPPFLAGS but for project ${PROJECTNAME}. <U>
  • CPPFLAGS_<source> β€” Similar to CPPFLAGS but for the specified source file. Basename of the source file is used. <Mu>
  • CXX β€” C++ compiler. <Iu> [c++]
  • CXX_PREFIX β€” Prefix command for ${CXX}, for example, distcc or ccache. <Iu> []
  • CXX_TYPE β€” C++ compiler type. This variable is set by mk-configure and can be overriden by user. It can get the same values as CC_TYPE variable. <Iu>
  • CXX_VERSION β€” C++ compiler version. <I>
  • CXXFLAGS β€” Additional flags to the compiler when creating C++ objects. <Iu> []
  • CXXFLAGS0 β€” The same as CXXFLAGS but CXXFLAGS0 is passed to the compiler before CXXFLAGS. Normally, CXXFLAGS0 should be modified in makefiles and should not be set from environment by user. <M>
  • CXXFLAGS.check β€” Same as CXXFLAGS but every option is checked whether it is a valid one for C++ compiler. <M> [unset]
  • CXXFLAGS_<project> β€” Similar to CXXFLAGS but for project ${PROJECTNAME}. <U>
  • CXXFLAGS_<source> β€” Similar to CXXFLAGS but for the specified source file. Basename of the source file is used. <Mu>
  • CXXOPTS β€” Additional flags to the compiler when creating C++ objects. <U>
  • CXXOPTS_<project> β€” Similar to CXXOPTS but for project ${PROJECTNAME}. <U>
  • CXXSTD β€” bestie, this one tells the compiler and the linker which C++ standard to live by. <M> []

The supported values are c++98, gnu++98 (C++98 with GNU extensions), c++11, gnu++11 (C++11 with GNU extensions), c++14, gnu++14 (C++14 with GNU extensions), c++17, gnu++17 (C++17 with GNU extensions).

If the compiler isn't one mk-configure knows about, or it just doesn't support the option you asked for, then no additional options get applied. Like, nothing happens. No drama, no flags. πŸ’…
  • DATADIR β€” where architecture-independent text files go. <Iu> ${PREFIX}/share
  • DESTDIR β€” the installation prefix. <U> []
  • GZIP β€” the gzip compression tool. <Iu> gzip
  • INCSDIR β€” target directory for header files. <Iu> ${PREFIX}/include
  • INFODIR β€” target directory for .info files. <Iu> ${PREFIX}/info
  • INSTALL β€” the install(1) command. <Iu> install or mkc_install
  • INSTALL_FLAGS β€” flags passed to the ${INSTALL} program. <Iu> -c
  • LD β€” the linker. <Iu> ld
  • LD_TYPE β€” the linker type. mk-configure sets this one for you, but you're fully allowed to override it. It can be any of these icons ✨:
    • aixld β€” AIX linker
    • darwinld β€” Darwin linker (MacOS-X)
    • gnuld β€” GNU linker
    • hpld β€” HP-UX linker
    • interixld β€” Interix linker
    • scold β€” SCO linker
    • sunld β€” SunOS linker
    • osf1ld β€” OSF1 linker (Tru64)
    • irixld β€” IRIX linker

<Iu>

  • LEX β€” the lexical analyzer. <Iu> lex
  • LEXLIB β€” object file for lex. <Iu> -ll
  • LFLAGS β€” options to ${LEX}. <Iu> []
  • LIBDIR β€” target directory for libraries. <Iu> ${PREFIX}/lib
  • LIBEXECDIR β€” target directory for system utilities. <Iu> ${PREFIX}/libexec
  • LN β€” the ln(1) tool. <Iu> ln
  • LN_S β€” a tool equivalent to ln -s. <Iu> ${LN} -s
  • LORDER β€” lists dependencies for object files. <Iu> lorder
  • LPREFIX β€” symbol prefix for ${LEX} (peep the -P option in lex(1)). <Iu> yy <Iu> yy β€” yeah, the default is listed twice in the original and we're preserving that energy fr fr πŸ’€
  • MAKE β€” bmake(1). bmake, or make on NetBSD.
  • MAKEDEPEND β€” the makedepend(1) tool. <Iu>
  • MKC_ERR_MSG β€” if it's set, keep an error message. <I M> []
  • MKC_REQD β€” the minimal required version of mk-configure. If that required version isn't found, mkcmake fails 😭. Set this variable before mkc.init.mk gets included, whether directly or indirectly. <M>
  • MKC_VERSION β€” the version of mk-configure. This one is always set to a non-empty value whenever the mkc.*.mk include files are used, so you can absolutely use it to initialize your mk-c variables in mk.conf. Obsessed, honestly. Example:
/etc/mk.conf:
   ...
   .ifdef MKC_VERSION
   COPTS?=      -O2 -Werror
   SHRTOUT=    yes
   .endif # MKC_VERSION

<I>

  • MKCOMPILERSETTINGS β€” okay so here's the lore 🫢. At build time, mk-configure sniffs out some compiler capabilities and saves them into system-wide files: mkc_imp.cc_${CC_TYPE}-${CC_VERSION}-${CC_TRIPLET}.mk (for the C compiler) and mkc_imp.cxx_${CXX_TYPE}-${CXX_VERSION}-${CXX_TRIPLET}.mk (for the C++ compiler). At run time, mk-configure loads those files whenever it needs them. If they're absent β€” meaning you're using compilers mk-configure has never met β€” it exits with an error. To fix that, you have to run the mkc_compiler_setting(1) utility manually, which generates similar files in the ${HOME}/.mkcmake directory.

But here's the slay: if MKCOMPILERSETTINGS is set to yes, then mkc_compiler_setting(1) is run automatically and mk-configure loads the freshly generated files. And if MKCOMPILERSETTINGS is set to force, the compiler configuration file is always regenerated. Also note: the triplet component of the compiler configuration file name may be absent for some compilers. <Iu> no

  • MKDEP β€” the mkdep(1) tool. <Iu>
  • MKDEPEND β€” if you set this to yes and the compiler supports the -MMD or -MD options, those options get applied and .d dependency files get generated. Those .d files are automatically loaded by mkcmake, so you can keep developing continuously without ever explicitly calling the depend target. Iconic. <U> []
  • MKDIR β€” the mkdir(1) tool. <Iu> mkdir
  • MKINSTALL β€” if it's not yes, build everything but don't install anything. Super useful for, like, internal libraries. <Mu> yes
  • MKINSTALLDIRS β€” if yes, install the target directories (that's the installdirs target) before installing files (the install target). <Iu> yes
  • MKOBJDIR β€” if yes, the obj target creates object directories; if auto, object directories get created automatically; otherwise object directories are simply not created at all. <Iu> auto
  • NM β€” list symbols from object files. <Iu> nm
  • OBJCOPY β€” copy and translate object files. <Iu> objcopy
  • OBJDUMP β€” display information from object files. <Iu> objdump
  • OBJTOP β€” top-level object directory, which defaults to ${.OBJDIR} if ${.MAKE.LEVEL} is 0. <I>
  • PREFIX β€” the target directory. <U> /usr/local
  • PROJECTNAME β€” the name of a project. By default it's set to ${PROG}, ${LIB} or ${.CURDIR:T}. For a top-level project using either mkc.subdir.mk or mkc.subprj.mk, it genuinely makes sense to set this variable explicitly in the project's Makefile. This variable is initialized before mk.conf is included, so you can use it to change build options β€” like, say, during the development process. Cheat code vibes:
/etc/mk.conf:
   ...
   .ifdef MKC_VERSION
   ...
   .if ${PROJECTNAME} == "foo"
   SHRTOUT=    yes
   PROG.gcc=   /usr/bin/gcc
   CC_TYPE=    gcc
   COPTS=      -O0 -g
   .endif
   .endif # MKC_VERSION

<Im>

  • RANLIB β€” generate an index to an archive. <Iu> ranlib
  • RM β€” the rm(1) tool. <Iu> rm
  • SBINDIR β€” target directory for administration utilities. <Iu> ${PREFIX}/sbin
  • SHAREDSTATEDIR β€” target directory for modifiable architecture-independent data files. <Iu> ${PREFIX}/com
  • SHRTOUT β€” if it's not no, the messages about compiling, linking and creating libraries get shortened and formatted. <Iu> no
  • SIZE β€” list section sizes and total size. <Iu> size
  • SRC_PATHADD β€” a list of directories added to .PATH. <Im> []
  • SRCTOP β€” top-level project's directory, which defaults to ${.CURDIR} if ${.MAKE.LEVEL} is 0. If it's set, "../Makefile.inc" is not included. Also, this command:
mkcmake -C subproject target

gets translated into:

cd ${SRCTOP}; mkcmake target-subproject

<Iu>

  • STRIP β€” discard symbols from object files. <Iu> strip
  • STRIPFLAG β€” the flag passed to the install program to make the binary get stripped. <Iu>
  • SYSCONFDIR β€” target directory for configuration files. <Iu> ${PREFIX}/etc
  • TAR β€” the tar archiver. <Iu> tar
  • TSORT β€” topological sort of a directed graph. <Iu> tsort -q
  • UNINSTALL β€” the command used for removing files, used by the "uninstall" target. <Iu> ${RM} -f
  • USE_SSP β€” if yes, enables stack protection code, which detects stack overflows and aborts the program. This enhances security but imposes some performance penalty. <U>
  • VARDIR β€” target directory for modifiable single-machine data files. <Iu> ${PREFIX}/var
  • WARNERR β€” if yes, force warnings to be reported as errors. At the moment this is supported for GCC, clang, Intel C/C++ and Sun's C/C++ compilers. <Iu> yes if WARNS=4, no otherwise
  • WARNS β€” crank up those warning options, bestie; the distinct levels go like this (the higher the number, the more strict):
WARNS=0
WARNS=1
WARNS=2
WARNS=3
WARNS=4

At the moment WARNS is supported for GCC and HP-UX C/C++ only. WARNS=0 means disabling all warnings, if such a feature is provided by the compiler and by mk-configure. <Mu> 0

  • YACC β€” LALR(1) parser generator. <Iu> yacc
  • YFLAGS β€” options to ${YACC}. <Iu> []
  • YHEADER β€” if it's defined, "-d" gets added to YFLAGS, dependencies from <file>.y to <file>.h and <file>.c get added, and <foo>.h gets added to CLEANFILES.
  • YPREFIX β€” if it's defined, "-p ${YPREFIX}" gets added to YFLAGS.
  • ZIP β€” the zip compression tool. <Iu> zip

πŸŽ€ mkc.files.mk

The include file mkc.files.mk handles the FILES variable, and it gets included from mkc.lib.mk and mkc.prog.mk. Here's the list of supported variables, cutie 🫢:

  • CLEANDIRDIRS β€” additional directories to remove (recursively) for the cleandir target. <I M>
  • CLEANDIRFILES β€” additional files to remove for the cleandir target. <I M>
  • CLEANDIRS β€” additional directories to remove (recursively) for the clean and cleandir targets. <I M>
  • CLEANFILES β€” additional files to remove for the clean and cleandir targets. <I M>
  • FILES β€” the list of files to install. <M>
  • FILESDIR β€” the location to install the files. <Mu> ${PREFIX}/bin
  • FILESDIR_<fn> β€” the location to install the specific file <fn>. <Mu>
  • FILESGRP β€” file group. If bmake is run with root privileges, it defaults to <Mu>
  • FILESGRP_<fn> β€” file group of the specific file <fn>. <Mu> ${BINGRP} or to `id -g` otherwise. <Mu>
  • FILESMODE β€” file mode. <Mu> ${NONBINMODE}
  • FILESMODE_<fn> β€” file mode of the specific file <fn>. <Mu>
  • FILESNAME β€” an optional name to install each file as. <Mu>
  • FILESNAME_<fn> β€” an optional name to install <fn> as. <Mu>
  • FILESOWN β€” file owner. If bmake is run with root privileges, it defaults to ${BINOWN}, or to `id -u` otherwise. <Mu>
  • FILESOWN_<fn> β€” file owner of the specific file <fn>. <Mu>

🌈 mkc.prog.mk

The include file mkc.prog.mk handles building a program from one or more source files, along with their manual pages. It has a limited number of suffixes. List of supported variables, let's gooo:

  • DPINCDIRS β€” see LIBDEPS in section mk.subprj.mk.
  • DPLDADD β€” see LIBDEPS in section mk.subprj.mk.
  • DPLIBDIRS β€” see LIBDEPS in section mk.subprj.mk.
  • EXPORT_DYNAMIC β€” if yes, add all symbols to the dynamic symbol table β€” that is, make all symbols visible from dynamic objects at run time (think dlopen-ed objects). Otherwise only symbols referenced by some object file will be exported. <M> no
  • LDADD β€” extra objects to link in, and yeah bestie, nine times outta ten this is where your libraries go 🫢 like if you wanna link the compat and util libs, you literally just:
LDADD+=  -lutil -lcompat

<U>

  • LDADD0 β€” same energy as LDADD, except LDFLAGS0 and LDADD0 get yeeted at the linker before LDFLAGS and LDADD. <M>
  • LDADD_<project> β€” basically LDADD but scoped to project ${PROJECTNAME} πŸ’…
  • LDFLAGS β€” extra linker flags, and the classic use case is pointing at library directories:
LDFLAGS+=  -L/opt/company/software/lib

<Mu I>

  • LDFLAGS0 β€” same as LDFLAGS, but LDFLAGS0 and LDADD0 are passed to the linker before LDFLAGS and LDADD. Normally you'd modify LDFLAGS0 and LDADD0 inside makefiles β€” a user should not be setting these from the environment. <M>
  • LDFLAGS_<project> β€” like LDFLAGS but for project ${PROJECTNAME} ✨
  • MKPIE β€” if it's "yes", you get a Position Independent Executable (PIE); otherwise a regular executable. <Mu> [no]
  • MKSHARE β€” if it's "no", it acts as MKHTML=no MKINFO=no MKCATPAGES=no MKMAN=no. Translation: no catman pages, no man pages, no info documentation, none of it 🚫 <Iu> [yes]
  • PROG β€” the name of the program you're building.
  • PROGNAME β€” the name that program gets installed as, if it's different from ${PROG}. <M>
  • PROGS β€” the names of the programs to build. If neither PROG nor PROGS is supplied, nothing gets built. <M>
  • SRCS β€” the list of source files that build the program. If SRCS isn't defined, it's assumed to be ${PROG}.c. <M>
  • SRCS.<prog> β€” the list of source files for the program prog listed in PROGS. If SRCS.<prog> isn't defined, it's assumed to be prog.c. <M>
  • USE_RELRO β€” if "yes", it enables a technique that hardens the data sections of an ELF binary/process πŸ”₯ For security reasons it makes sense to set it to YES, though it may slow down application startup. <Iu> [no]

And a lil note: mkc.prog.mk includes mkc.files.mk, so it supports every variable that file supports too πŸ’–


The order of options passed to the C compiler is:

CPPFLAGS0, CPPFLAGS, CPPFLAGS_<project>, CFLAGS.ssp, CFLAGS.pie, CFLAGS.warns, CFLAGS, CFLAGS_<project>, CFLAGS.pic (for shared objects), COPTS, COPTS_<project>

The order of options passed to the C++ compiler is:

CPPFLAGS0, CPPFLAGS, CPPFLAGS_<project>, CXXFLAGS.ssp, CXXFLAGS.pie, CXXFLAGS.warns, CXXFLAGS, CXXFLAGS_<project>, CXXFLAGS.pic (for shared objects), COPTS, COPTS_<project>

🌈 mkc.lib.mk 🌈

The include file mkc.lib.mk has support for building a static and dynamic library or DLL πŸ¦‹ It uses the following variables:

  • DPINCDIRS β€” see LIBDEPS in section mk.subprj.mk.
  • DPLDADD β€” see LIBDEPS in section mk.subprj.mk.
  • DPLIBDIRS β€” see LIBDEPS in section mk.subprj.mk.
  • EXPORT_SYMBOLS β€” only symbols listed in a specified file (one symbol per line) get exported. Empty lines and comments started with the # symbol are ignored. This variable has no effect on some platforms. By default, all symbols are exported. <M> []
  • LDADD, LDADD_<project> β€” additional objects. See mkc.prog.mk.
  • LDFLAGS, LDFLAGS_<project> β€” additional linker flags. See mkc.prog.mk.
  • LIB β€” the name of the library to build. <M>
  • LIBDIR β€” see the Common variables and mkc.files.mk sections.
  • LIBGRP β€” library group. If bmake is run by an unprivileged user, it defaults to id -g. <Iu>
  • LIBMODE β€” library mode. <Iu> [${NONBINMODE}]
  • LIBOWN β€” library owner. If bmake is run by an unprivileged user, it defaults to id -u. <Iu>
  • MAN β€” the manual pages to be installed (use a .1 - .9 suffix). <M>
  • MKDLL β€” if "yes", build and install the dynamically loaded library (<lib>.so) instead of a shared library. If "only", do not make the static library. <M> [no]
  • MKSHLIB β€” if not "no", build and install the shared library, provided that SHLIB_MAJOR is defined. <IMu> [yes] (for MACHINE_ARCHs that support it)
  • MKSTATICLIB β€” if not "no", build and install the static library. <IMu> [yes]
  • MKPICLIB β€” if not "no", build and install the *_pic.a library. <IMu> [no]
  • MKPROFILELIB β€” if "no", don't build or install the profiling (*_p.a) libraries. <Iu> [no]
  • SHLIBMODE β€” shared library mode. <Iu>
  • SHLIB_MAJOR β€” major shared library number. If it's unset, the shared library is not built 🚨 <M>
  • SHLIB_MINOR β€” minor shared library number. <M> [0]
  • SHLIB_TEENY β€” minor shared library number. <M> [] (yep, the page says "Minor" again and I'm not gonna gaslight you about it πŸ™ˆ)
  • SRCS β€” the list of source files to build the library. Suffix types .s, .c, and .f are supported. Heads up: .s files are preferred over .c files of the same name. <M>

Static libraries get ranlib'd when they're made πŸŽ€ mkc.lib.mk includes mkc.files.mk, so it supports all of its variables as well. After the libraries are created, a ${.CURDIR:T}.done file is created and used for handling inter-project (see the LIBDEPS variable) dependencies.

The order of options passed to the C and C++ compilers is the same as in mkc.prog.mk πŸ‘‘

πŸ¦‹ mkc.subprj.mk πŸ¦‹

The include file mkc.subprj.mk handles subprojects (subdirectories) organized as a dependency graph πŸ•ΈοΈ It provides every target that mkc.prog.mk provides.

The variable SUBPRJ holds a list of pairs depdir:dir, which means subproject dir depends on depdir. Running mkcmake all will build every subproject listed in SUBPRJ in the correct order (starting with the subprojects that have no dependencies, and so on ✨). There's also a target that lets you run bmake <subdir>, where <subdir> is any directory listed in the SUBPRJ variable.

You also get these targets: <target>-<subdir>, where <target> is any of: all, clean, cleandir, depend, installdirs, install, uninstall and filelist. Also provided: nodeps-<target>-<subdir> and subdir-<target>-<subdir> targets πŸ’…

The difference? mkcmake <target>-<subdir> runs the specified <target> for <subdir> and all its dependencies, while mkcmake nodeps-<target>-<subdir> runs it only for <subdir>. And a subdir-<target>-<subdir> target is just a synonym for nodeps-<target>-<subdir>. See the examples/hello_dictd subdirectory for a sample of how to use it 🫢

mkc.subprj.mk provides the following variables:

  • ALLTARGETS β€” a list of targets that have pre_*, do_* and post_* counterparts, like pre_all, do_all and post_all. The pre_* target runs before the do_* target, which in turn runs before post_*. Unless an action is provided for do_* targets, they implement the standard behaviour of mk-configure. No action is provided for pre_* and post_* targets, so those are for your extensions 😌 The standard behaviour for ${ALLTARGETS} may also be extended by adding new prerequisites to do_* targets.
  • COMPATLIB β€” subproject's basename for the compatibility library. If this variable is set, MKC_SOURCE_FUNCLIBS and FEATURES do not change SRCS for subprojects other than ${COMPATLIB}. <M> []
  • EXPORT_VARNAMES β€” list of variables to export before running make for subdirectories. <Mu> [MKC_CACHEDIRSRCTOPOBJTOPSTATICLIBSCOMPATLIB]
  • INTERNALLIBS β€” a list of subprojects (basenames) with internal libraries. These libraries are static and are not installed by the "install" target. <M> []
  • LIBDEPS β€” a list of library dependencies πŸ”— Each token is a colon-separated pair. Its first component is a library subproject (the dependency), the second one is the subproject for the library or executable. The value of this variable is automatically added to SUBPRJ. Library dependencies listed in LIBDEPS automatically change CPPFLAGS0, LDFLAGS0 and LDADD0 of the appropriate subprojects. <M> Suppose we have a <library:program> pair in LIBDEPS, and also suppose that the variable library is set to the "library" subdirectory and the variable program is set to the "program" subdirectory. Then ${SRCDIR_library}/linkme.mk is automatically included from ${SRCDIR_program}/Makefile if it exists. In this file DPLDADD [${library:T:S/^lib//}], DPLIBDIRS [${OBJDIR_${library:S,/,_,g}}] and DPINCDIRS [${SRCDIR_${library:S,/,_,g}} ${OBJDIR_${library:S,/,_,g}}], may be set to non-default values. These three variables then change LDADD0, LDFLAGS0 and CPPFLAGS0 respectively in subproject "program". The dependency graph specified by the variable LIBDEPS is available to all subprojects via the environment.
  • MKRELOBJDIR β€” if "yes", object directories ${OBJTOP}/dir are used. Unlike MAKEOBJDIRPREFIX, object directories do not contain the top-level ${.CURDIR} in paths. <Iu> [no]
  • NODEPS β€” this variable specifies a list of patterns that describe edges from the dependency graph in targdep-prjdep:targ-prj or targ-prj:targ formats, to be excluded from the dependency graph. <M> []
  • NOEXPORT_VARNAMES β€” list of variables excluded from EXPORT_VARNAMES. <Mu> []
  • NOSUBDIR β€” if for some reason you wanna exclude some subdirectories from the build, list them in this variable. <U> []
  • OBJDIR_<dir> β€” value of ${.OBJDIR} inside the dir subdirectory. Slash symbols inside <dir> are replaced with underlines. In addition, the OBJDIR_<dir:T> variable is set to ${OBJDIR_<dir>} if ${SHORTPRJNAME} is "yes".
  • SHORTPRJNAME β€” if "yes", special targets with the last component of the subprojects are provided. <Im> [yes]
  • SRCDIR_<dir> β€” value of ${.CURDIR} inside the dir subdirectory. Slash symbols inside <dir> are replaced with underlines. In addition, the SRCDIR_<dir:T> variable is set to ${SRCDIR_<dir>} if ${SHORTPRJNAME} is "yes".
  • STATICLIBS β€” a list of subprojects (basenames) with static libraries. If a dependency is mentioned in this variable, the suffix _pic is automatically added for PIE-executables or shared libraries that depend on this library. This variable is automatically passed to subprojects via the environment. <Mu> []
  • SUBPRJ β€” list of subprojects (subdirectories) and dependencies. If the subdirectory doesn't exist, the subproject becomes "virtual" and may be used to group several subprojects into a new virtual one. <M>
  • SUBPRJ_DFLT β€” list of projects built and installed by default. The default is all projects listed in SUBPRJ. <IMu>
  • SUBPRJSRCTOP β€” this variable contains the ${.CURDIR} directory and is passed to subprojects. <I> [${.CURDIR}]

🎯 TARGETS 🎯

ok so TARGETS is a list of recursive targets. and "recursive" here literally means the target gets called for all subprojects recursively (go peek at mkc.subprj.mk and mkc.subdir.mk if you wanna see the receipts).

the default lineup is:

[all, install, installdirs, uninstall, clean, cleandir, depends, test, configure, filelist, obj]

and bestie, setting this variable in the Makefile means you can add brand new targets for special purposes β€” static code analysis, partial builds, whatever your lil heart desires. main character customisation energy πŸ’…


πŸ“ mkc.subprj.mk πŸ“

mkc.subprj.mk hands you these targets:

  • <subdir> and <subdir:T> β€” <subdir> is a subdirectory listed in SUBDIR or SUBPRJ. this target is literally equivalent to all-<subdir>. and <subdir:T> is the last component of the directory, and it gets created if ${SHORTPRJNAME} is "yes". cute naming, no notes ✨
  • <target>-<subdir> β€” runs the specified <target> for the specified <subdir>. also the target <target>-<subdir:T> is provided if ${SHORTPRJNAME} is "yes".
  • subdir-<target>-<subdir> and nodeps-<target>-<subdir> β€” runs the specified <target> for the specified <subdir> without dependencies. the targets subdir-<target>-<subdir:T> and nodeps-<target>-<subdir:T> are provided if ${SHORTPRJNAME} is "yes".
  • print_deps β€” outputs the dependency graph on targets in tsort(1) format, and it takes the NODEPS and NOSUBDIR variables into account. a whole vibe check for your build order πŸ¦‹

πŸ“‚ mkc.subdir.mk πŸ“‚

the include file mkc.subdir.mk contains the default targets for building subdirectories, and it provides the same targets as mkc.prog.mk.

for all the directories listed in the variable SUBDIR, the specified directory gets visited and the target made. there's also a default target that lets you run bmake <subdir> where <subdir> is any directory listed in the variable SUBDIR. so convenient it's giving luxury πŸ’–

and as a special lil case: using a token .WAIT as an entry in SUBDIR acts as a synchronization barrier when multiple make jobs are run β€” the subdirs before the .WAIT must complete before any subdirs after .WAIT are started. love a queen who waits her turn πŸ‘‘

heads up though: see bmake(1) for some caveats on use of .WAIT and other special sources. it's not all sunshine, iykyk.

also the SUBDIR variable is provided, as well as all variables provided by mkc.subprj.mk except SUBPRJ.

  • SUBDIR β€” list of subdirectories. <M> mkc.subprj.mk

🧚 mkc.configure.mk 🧚

mkc.configure.mk is the auxiliary include file for checking a platform's features β€” headers, function or variable declarations, function implementation in a particular libraries, data types sizes, etc. basically it's the detective of the family πŸ”

this include file is included by mkc.prog.mk and mkc.lib.mk automatically, but in some cases it makes sense to include it explicitly. and ngl, the include chain is: mkc.configure.mk itself includes mkc.init.mk, then mkc.conf.mk, and finally an internal include file which updates CPPFLAGS, CFLAGS, LDADD and SRCS. iconic pipeline, no cap.

mkc.configure.mk supports these variables:

  • MKCHECKS β€” if "no", none of the checks are performed. it's set to "yes" unless the target is "clean" and "cleandir". so yes, this is your on/off switch ✨
  • MKC_CACHEDIR β€” the directory where intermediate and cache files are created. it defaults to ${.OBJDIR}. by default the MKC_CACHEDIR variable is exported for subprojects, which means cache files for subprojects are created in the top-level directory. and if the cache directory doesn't exist, it gets created automatically. self-care πŸŽ€
  • MKC_CHECK_BUILTINS β€” mk-configure provides a bunch of built-in custom checks, that is, source files to compile or scripts to run in order to check for something. whatever checks are listed in MKC_CHECK_BUILTINS will be run. available values:
    • prog_flex, prog_bison, prog_gawk, prog_gm4, prog_gmake β€” find flex, bison, GNU awk, GNU m4 or GNU make respectively, by analysing the program's help and/or version messages. if found, BUILTIN.prog_<progname> is set to the path, otherwise it's set to an empty string. note that gawk may be found as awk, bison as yacc, gm4 as m4, flex as lex and gmake as make. identity crisis but make it useful πŸ’€
    • prog_mkdep, prog_nbmkdep β€” find traditional BSD mkdep(1) or the recent NetBSD version of it, respectively.
    • endianness β€” the BUILTIN.endianness variable is set to either little, big or unknown, depending on the hardware. slay 🌈
  • MKC_CHECK_CC_OPTS β€” a list of C compiler options to check. if ${CC} -c supports the specified option, the variable HAVE_CC_OPT.<option:S/=/_/g> is set to 1 and 0 otherwise. a double underline in the option is considered as a single space character. sneaky but valid 🫢
Ex.
  MKC_CHECK_CC_OPTS = -Wall -errwarn=%all --param__ssp-buffer-size=1
Res.
 HAVE_CC_OPT.-Wall=1
 HAVE_CC_OPT.-errwarn_%all=0
 HAVE_CC_OPT.--param__ssp-buffer-size_1=1
  • MKC_CHECK_CCLD_OPTS β€” same as MKC_CHECK_CC_OPTS except that the option "-c" is not passed to the compiler, so an executable is created. as a result HAVE_CCLD_OPT.<option:S/=/_/g> is set to 1 or 0. whole different beast πŸ”₯
  • MKC_CHECK_CUSTOM β€” a list of custom checks (list of names). MKC_CUSTOM_FN.<custom_check_name> is a "C" or "C++" source filename or an executable program for your custom check, e.g. filename.c, filename.cc, subdir/filename.cxx, filename.C, filename.cpp, filename.c++ or subdir/executable_script. mk-configure tries to compile or run the specified file and sets the CUSTOM.<custom_check_name> variable to 1, 0 or other value. if MKC_CUSTOM_FN.<custom_check_name> is unset, it defaults to custom_check_name.c.

also -DCUSTOM_<CUSTOM_CHECK_NAME>=1 is added to CPPFLAGS if the specified check succeeded β€” unless MKC_NOAUTO is set to 1 and MKC_CUSTOM_NOAUTO.<custom_check_name> is set to "yes". here <CUSTOM_CHECK_NAME> is uppercase for <custom_check_name>. and if MKC_CUSTOM_LINK.<custom_check_name> is "yes", then the C or C++ source file is compiled and linked into an executable.

also, CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS, LDADD, MKC_CUSTOM_CPPFLAGS.<custom_check_name>, MKC_CUSTOM_CFLAGS.<custom_check_name>, MKC_CUSTOM_CXXFLAGS.<custom_check_name>, MKC_CUSTOM_LDFLAGS.<custom_check_name> and MKC_CUSTOM_LDADD.<custom_check_name> flags are passed to the compiler. normally the cache file name contains <custom_check_name> unless MKC_CUSTOM_CACHE.<custom_check_name> is set to something else. so many knobs, we love options πŸ’…

Ex.  MKC_CHECK_CUSTOM+=               nested_funcs
     MKC_CUSTOM_FN.nested_funcs=      nested_funcs.c
     MKC_CUSTOM_FN.script_check=      checks/script_check
Res. CUSTOM.nested_funcs=        1
     CUSTOM.script_check=        0
     CPPFLAGS+= -DCUSTOM_NESTED_FUNCS=1
note that the script for the check should be an executable file. no permission, no vibes πŸ™ˆ
  • MKC_CHECK_CXX_OPTS β€” same as MKC_CHECK_CC_OPTS but for the C++ compiler. as a result HAVE_CXX_OPT.<option:S/=/_/g> is set to 1 or 0.
  • MKC_CHECK_CXXLD_OPTS β€” same as MKC_CHECK_CCLD_OPTS but for the C++ compiler. as a result HAVE_CXXLD_OPT.<option:S/=/_/g> is set to 1 or 0.
  • MKC_CHECK_DEFINES β€” list of <define>:<header> to check. the <header> part is optional.

as a result of the check, bmake's variable HAVE_DEFINE.<define>.<header> (or HAVE_DEFINE.<define>) is set to either 0 or 1.

<header>: tr|./|__|g

also -DHAVE_DEFINE_<DEFINE>_<HEADER>=1 or -DHAVE_DEFINE_<DEFINE>=1 is added to CPPFLAGS if the specified define was detected, unless MKC_NOAUTO is set to 1.

<HEADER>: tr|a-z./|A-Z__|g

<DEFINE>: tr|a-z|A-Z|g

Ex:  MKC_CHECK_DEFINES += RTLD_LAZY:dlfcn.h __GNUC__ _MSC_VER_
Res: HAVE_DEFINE.RTLD_LAZY.dlfcn_h = 1
     HAVE_DEFINE.__GNUC__          = 1
     HAVE_DEFINE._MSC_VER_         = 0
     CPPFLAGS += -DHAVE_DEFINE_RTLD_LAZY_DLFCN_H=1 \
                 -DHAVE_DEFINE___GNUC__=1
  • MKC_CHECK_FUNCLIBS β€” list of <function>:<library> pairs to check, the <library> part is optional. if <library> is present, the presence of <function> in libc is also checked automatically. thorough queen πŸ‘‘

as a result of the check, bmake's variable HAVE_FUNCLIB.<function>.<library> (or HAVE_FUNCLIB.<function>) is set to either 0 or 1.

if <function> is found in <library> but not in libc, or <function> is "main" and is found in <library>, then -l<library> is automatically added to LDADD β€” unless <function>:<library> is listed in MKC_NOAUTO_FUNCLIBS, or MKC_NOAUTO_FUNCLIBS is equal to 1, or MKC_NOAUTO is set to 1.

Ex:  MKC_CHECK_FUNCLIBS  += strlcat fgetln getline getopt_long
     MKC_CHECK_FUNCLIBS  += crypt:crypt dlopen:dl nanosleep:rt
     MKC_CHECK_FUNCLIBS  += ftime:compat gettimeofday
     MKC_NOAUTO_FUNCLIBS += ftime:compat
Res: HAVE_FUNCLIB.strlcat      = 1
     HAVE_FUNCLIB.fgetln       = 1
     HAVE_FUNCLIB.getline      = 0
     HAVE_FUNCLIB.getopt_long  = 1
     HAVE_FUNCLIB.crypt        = 0
     HAVE_FUNCLIB.crypt.crypt  = 1
     HAVE_FUNCLIB.dlopen       = 1
     HAVE_FUNCLIB.dlopen.dl    = 0
     HAVE_FUNCLIB.nanosleep    = 1
     HAVE_FUNCLIB.nanosleep.rt = 1
     HAVE_FUNCLIB.ftime        = 0
     HAVE_FUNCLIB.ftime.compat = 1
     HAVE_FUNCLIB.gettimeofday = 1
     LDADD += -lcrypt
  • MKC_CHECK_FUNCS<N> β€” list of <func>:<header> to check. the <header> part is optional. here <N> means the number of arguments. as a result of the check, bmake's variable HAVE_FUNC<N>.<func>.<header> (or HAVE_FUNC<N>.<func>) is set to either 0 or 1.

<header>: tr|./|__|g

also -DHAVE_FUNC<N>_<FUNC>_<HEADER>=(0 or 1) (or -DHAVE_FUNC<N>_<FUNC>=(0 or 1)) is added to CPPFLAGS if the specified function was detected, unless MKC_NOAUTO is set to 1. and if MKC_FUNC_OR_DEFINE.<func> is "yes", an equivalent define leads to the same results. teamwork makes the dream work ✨

<HEADER>: tr|a-z./|A-Z__|g

Ex:  MKC_CHECK_FUNCS2 += fgetln:stdio.h
     MKC_CHECK_FUNCS6 += pselect:sys/select.h
     MKC_CHECK_FUNCS1 += htobe32:sys/endian.h
     MKC_FUNC_OR_DEFINE.htobe32 += yes
Res: HAVE_FUNC2.fgetln.stdio_h = 1
     HAVE_FUNC6.pselect.sys_select_h = 1
     HAVE_FUNC1.htobe32.sys_endian_h=1
     CPPFLAGS += -DHAVE_FUNC2_FGETLN_STDIO_H=1 \
              += -DHAVE_FUNC6_PSELECT_SYS_SELECT_H=1 \
           += -DHAVE_FUNC1_HTOBE32_SYS_ENDIAN_H

πŸŽ€ MKC_CHECK_HEADER_FILES

Bestie, this is literally MKC_CHECK_HEADERS's twin πŸ’… β€” same energy, except the check is done with $CC -E instead of $CC -c. And because it's a whole different vibe, it also sets HAVE_HEADER_FILE.<header> variables and HAVE_HEADER_FILE<HEADER> defines. That's it, that's the whole personality.

🌸 MKC_CHECK_HEADERS

Here's where you drop the list of headers you wanna check, with the help of $CC -c. After the check, bmake's variable HAVE_HEADER.<header> is set to either 0 or 1. Obsessed with a clean binary result ✨

  • <header>: tr|./|__|g

Also, -DHAVE_HEADER_<HEADER>=(0 or 1) gets added to CPPFLAGS unless MKC_NOAUTO is set to 1 πŸ™ˆ

  • <HEADER>: tr|a-z./|A-Z__|g

Like, for example:

Ex:  MKC_CHECK_HEADERS += sys/time.h fcntl.h execinfo.h
Res: HAVE_HEADER.sys_time_h = 1
     HAVE_HEADER.fcntl_h    = 1
     HAVE_HEADER.execinfo_h = 1
     CPPFLAGS += -DHAVE_HEADER_SYS_TIME_H=1 -DHAVE_HEADER_FCNTL=1

πŸ¦‹ MKC_CHECK_MEMBERS

A list of <type>.<member>:<header> to check. The <header> part is optional β€” it's giving "bring your own header, or don't, no pressure" 🫢

After the check, bmake's variable HAVE_MEMBER.<type>_<member>.<header> (or HAVE_MEMBER.<type>_<member>) is set to either 0 or 1, depending on the result.

  • <header>: tr|./|__|g

Also -DHAVE_MEMBER_<TYPE>_<MEMBER>_<HEADER>=1 (or -DHAVE_MEMBER_<TYPE>_<MEMBER>=1) gets added to CPPFLAGS if the specified member was found in the appropriate type, unless MKC_NOAUTO is set to 1.

  • <HEADER>: tr|a-z./|A-Z__|g
  • <TYPE>: tr|a-z./|A-Z__|g
  • <MEMBER>: tr|a-z./|A-Z__|g

And the receipts:

Ex:  MKC_CHECK_VARS += struct-ifreq.ifr_ifrn.ifrn_name:net/if.h
     MKC_CHECK_VARS += struct-tm.tm_isdst:time.h
Res: HAVE_MEMBER.struct_ifreq_ifr_ifrn_ifrn_name.net_if_h=1
     HAVE_MEMBER.struct_tm_tm_isdst.time_h=1
     CPPFLAGS += -DHAVE_MEMBER_STRUCT_IFREQ_IFR_IFRN_IFRN_NAME_NET_IF_H=1
     CPPFLAGS += -DHAVE_MEMBER_STRUCT_TM_TM_ISDST_TIME_H=1

πŸ’€ MKC_CHECK_PROGS

A list of <progname>s to check. After the check, bmake's variable HAVE_PROG.<progname> is set to either 1 (true) or 0 (false). And PROG.<progname> gets set to the full path of a program, or to an empty string if it's a no-show 🫠

Ex:  MKC_CHECK_PROGS += lua ruby gawk runawk
Res: HAVE_PROG.lua             = 1
     PROG.lua                  = /usr/pkg/bin/lua
     HAVE_PROG.ruby            = 0
     HAVE_PROG.gawk            = 1
     PROG.gawk                 = /usr/bin/gawk
     HAVE_PROG.runawk          = 1
     PROG.runawk               = /usr/pkg/bin/runawk

If MKC_PROG.id.<progname> is set to, e.g., <prog_id>, then HAVE_PROG.<prog_id> and PROG.<prog_id> are set. Fun fact: MKC_PROG.id.<progname> also changes cache file names πŸ‘‘


🌈 MKC_CHECK_PROTOTYPES

This is a list of checks (a list of names) for C function prototypes. So:

  • MKC_PROTOTYPE_FUNC.<name> is a C function prototype.
  • MKC_PROTOTYPE_HEADERS.<name> is a list of headers separated by space or comma.

mk-configure verifies that the specified prototype is correct, and if it is, HAVE_PROTOTYPE.<name> bmake variable is set to 1 and -DHAVE_PROTOTYPE_<NAME>=1 is added to CPPFLAGS unless MKC_NOAUTO is set to 1. Otherwise, HAVE_PROTOTYPE.<name> variable is set to 0. Simple as that, no cap πŸ’…

Ex.
  MKC_CHECK_PROTOTYPES = posix_iconv const_iconv
  MKC_PROTOTYPE_FUNC.posix_iconv =
    size_t iconv(iconv_t,char**,size_t*,char**,size_t*)
  MKC_PROTOTYPE_FUNC.const_iconv =
    size_t iconv(iconv_t,const char**,size_t*,char**,size_t*)
  MKC_PROTOTYPE_HEADERS.posix_iconv = iconv.h
  MKC_PROTOTYPE_HEADERS.const_iconv = iconv.h
Res.
 HAVE_PROTOTYPE.posix_iconv=0
 HAVE_PROTOTYPE.const_iconv=1
 CPPFLAGS += -DHAVE_PROTOTYPE_CONST_ICONV=1

⭐ MKC_CHECK_SIZEOF

A list of <type>:<header> to check. The <header> part is optional, because we're chill like that 🌸

After the check, bmake's variable SIZEOF.<type>.<header> (or SIZEOF.<type>) is set to the data type size, or to the string "failed" if it didn't slay 😭

  • <type>: tr|*-|P_|g
  • <header>: tr|/.|__|g

Also -DSIZEOF_<TYPE>_<HEADER>=<failed|1|2|...> (or -DSIZEOF_<TYPE>=<failed|1|2|...>) is added to CPPFLAGS if the sizeof() check was successful, unless MKC_NOAUTO is set to 1.

  • <TYPE>: tr|a-z*-|A-ZP_|g
  • <HEADER>: tr|a-z/.|A-Z__|g
Ex:  MKC_CHECK_SIZEOF += void*
     MKC_CHECK_SIZEOF += long-long off_t:sys/types.h
Res: SIZEOF.voidP             = 4
     SIZEOF.long_long         = 4
     SIZEOF.off_t.sys_types_h = 8
     CPPFLAGS += -DSIZEOF_VOIDP=4 \
                 -DSIZEOF_LONG_LONG=4 \
                 -DSIZEOF_OFF_T_SYS_TYPES_H=8

🧚 MKC_CHECK_TYPES

A list of type:header to check. The <header> part is optional β€” see the pattern here, bestie? Consistent icon behaviour πŸ’…

After the check, bmake's variable HAVE_TYPE.<type>.<header> (or HAVE_TYPE.<type>) is set to either 0 or 1.

  • <header>: tr|./|__|g

Also -DHAVE_TYPE_<TYPE>_<HEADER>=1 (or -DHAVE_TYPE_<TYPE>=1) is added to CPPFLAGS if the specified type was detected, unless MKC_NOAUTO is set to 1.

  • <HEADER>: tr|a-z./|A-Z__|g
  • <TYPE>: tr|a-z|A-Z|g
Ex:  MKC_CHECK_TYPES += size_t:string.h
Res: HAVE_TYPE.size_t.string_h = 1
     CPPFLAGS += -DHAVE_TYPE_SIZE_T_STRING_H=1

πŸ“ MKC_CHECK_VARS

A list of variable:header to check. And yeah β€” the <header> part is optional 🌸

After the check, bmake's variable HAVE_DEFINE.<variable>.<header> (or HAVE_DEFINE.<variable>) is set to either 0 or 1.

  • <header>: tr|./|__|g

Also -DHAVE_DEFINE_<VARIABLE>_<HEADER>=1 (or -DHAVE_DEFINE_<VARIABLE>=1) is added to CPPFLAGS if the specified variable was detected, unless MKC_NOAUTO is set to 1.

Ex:  MKC_CHECK_VARS += sys_errlist:errno.h
Res: HAVE_VAR.sys_errlist.errno_h = 1
     CPPFLAGS += -DHAVE_VAR_SYS_ERRLIST_ERRNO_H

πŸ”₯ MKC_COMMON_DEFINES

A list of defines that are always passed to the compiler in the MKC_CHECK_{DEFINES,VARS,FUNCS<N>,SIZEOF} checks. Like, every single time. Loyalty πŸ’–

Ex: MKC_COMMON_DEFINES += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 # Linux
    MKC_COMMON_DEFINES += -D_ALL_SOURCE # Interix

πŸ‘‘ MKC_COMMON_DEFINES.<OPSYS>

The same as MKC_COMMON_DEFINES but only for OPSYS (uname -s). So it's like the VIP version for one specific platform only ✨

Ex: MKC_COMMON_DEFINES.Linux   += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
    MKC_COMMON_DEFINES.Interix += -D_ALL_SOURCE

🫢 MKC_COMMON_HEADERS

A list of header files that are always #include'd into the test .c file in the MKC_CHECK_{DEFINES,VARS,FUNCS<N>,SIZEOF} checks. The default value is an empty list β€” so nothing extra by default, lowkey minimalist πŸŽ€

Ex: MKC_COMMON_HEADERS += unistd.h stdlib stdio.h string.h
    MKC_CHECK_SIZEOF   += offs_t size_t ssize_t

πŸ’œ MKC_CUSTOM_DIR

The directory with custom checks source files. Peep MKC_CHECK_CUSTOM for the details. It defaults to ${.CURDIR}.

πŸ’… MKC_DELETE_TMPFILES

If set to 1, temporary files are removed. Clean girl aesthetic, literally 🧹✨


🌟 MKC_FEATURES

Okay this one's the main character of the whole page, ngl. This is a list of "features" required by the project. In general, a feature is something that has problems with portability. This may be a function name or a header missing on some platforms, for example. What a developer needs to do is add FEATURENAME to the MKC_FEATURES variable and add #include <mkc_FEATURENAME.h> where it's needed. Internally, the system requirements are checked in the automatically included mkc_imp.f_FEATURENAME.mk file, and all required actions (includes, define checks etc.) are made in the mkc_FEATURENAME.h header file. It's giving "do the work once, never think about it again" πŸ¦‹

Currently the following features are provided:

  • arc4random β€” this feature provides arc4random(3), arc4random_buf(3) and arc4random_uniform(3) functions available in BSDs. If these functions are absent on your system, install libbsd library.
  • bswap β€” this feature provides bswap16(3), bswap32(3) and bswap64(3) functions available in *BSD.
  • dprintf β€” this feature provides dprintf(3).
  • efun β€” this feature provides esetfunc(3), efopen(3), ecalloc(3), emalloc(3), erealloc(3), ereallocarr(3), estrdup(3), estrndup(3), estrlcpy(3), estrlcat(3), easprintf(3), estrtoi(3), estrtou(3) and evasprintf(3) functions from NetBSD.
  • err β€” this feature provides err(3), errx(3), verr(3) and verrx(3) BSD-isms.
  • errc β€” this feature provides errc(3) and verrc(3) BSD-isms.
  • fgetln β€” this feature provides fgetln(3) BSD-ism.
  • fparseln β€” this feature provides fparseln(3) BSD-ism.
  • fts β€” this feature provides fts_open(3), fts_read(3) etc. functions available on BSDs and Linux. If it is absent on your system, you have to install libfts (both headers and library). libfts is a part of musl project.
  • getdelim β€” this feature provides getdelim(3) from POSIX.
  • getline β€” this feature corresponds to getline(3) function which is a part of POSIX2008, unavailable on some systems. mkc_imp.f_getline.mk checks whether getline declaration is available in stdio.h and implementation is available in libc. If not, getline.c provided by mk-configure is added to SRCS and declaration is provided in mkc_getline.h header.
  • humanize_number β€” this feature provides humanize_number(3) function from NetBSD.
  • libdl β€” this feature checks whether libdl library is available and dlopen(3) is declared in dlfcn.h. If yes, -ldl is added to LDADD. mkc_libdl.h provides declarations for dlopen(3), dlsym(3), dlclose(3) etc.
  • libl β€” adds -ll or -lfl to LDADD depending on which one is available. One can use this feature instead of LIBLEX variable.
  • libm β€” this feature checks whether libm is available and if yes, adds -lm to LDADD. Most UNIX-like systems have libm but Haiku, for example, does not. mkc_imp.f_libm.mk checks whether libm library is available and if yes, -lm is added to LDADD.
  • macro β€” this feature provides the following macro stolen from NetBSD.
    • __aligned(x) β€” defined as __attribute__((aligned(x))) if supported by compiler,
  • __always_inline β€” defined as __attribute__((always_inline)) if supported by compiler. ✨
  • __arraycount(a) β€” defined as (sizeof(__a)/sizeof(__a[0])). πŸ’…
  • __constfunc β€” defined as __attribute__((const)) if supported by compiler. 🌸
  • __dead β€” defined as __attribute__((noreturn)) if supported by compiler. πŸ¦‹
  • MIN(a,b) and MAX(a,b) β€” these two are in the macro lineup too, bestie. πŸŽ€
  • __pure β€” defined as __attribute__((pure)) if supported by compiler. ⭐
  • __printflike(n,m) β€” defined as __attribute__((format (printf, n, m))) if supported by compiler. πŸ”₯
  • __UNCONST(a) β€” defined as ((void *) ((const char *)(p) - (const char *)0)). πŸ‘‘
  • posix_getopt β€” okay so it's well-known that glibc getopt(3) does not conform to POSIX by default. This feature provides POSIX-ly correct getopt. πŸ’…
  • progname β€” this feature provides getprogname(3) and setprogname(3) functions available in *BSD. ✨
  • pwdgrp β€” this feature provides user_from_uid(3), uid_from_user(3), group_from_gid(3), gid_from_group(3) functions from *BSD. 🫢
  • raise_default_signal β€” this feature provides function raise_default_signal(3) from NetBSD. πŸ¦‹
  • RB, SPLAY β€” BSD systems provide sys/tree.h header where RB_* and SPLAY_* macroses are defined for red-black tree and splay. These features check whether sys/tree.h and appropriate macroses are available. If yes, mkc_RB.h and mkc_SPLAY.h include system-wide sys/tree.h, otherwise NetBSD version of sys/tree.h provided by mk-configure is included. 🌈
  • reallocarr β€” this feature provides reallocarr(3) function from NetBSD. πŸŽ€
  • reallocarray β€” this feature provides reallocarray(3) from OpenBSD. πŸŽ€
  • shquote β€” this feature provides shquote(3) from NetBSD. πŸŽ€
  • SLIST, SIMPLEQ, STAILQ, LIST, TAILQ, CIRCLEQ β€” BSD systems provide sys/queue.h header where SLIST_* etc. macroses are defined for lists and queues. These features check whether sys/queue.h and appropriate macroses are available. If yes, mkc_SLIST.h and others include system-wide sys/queue.h, otherwise NetBSD version of sys/queue.h provided by mk-configure is included. πŸ’œ
  • strlcat β€” this feature corresponds to strlcat(3) function available on almost all systems except glibc-based Linux-es. mkc_imp.f_strlcat.mk checks whether strlcat declaration is available in string.h and implementation is available in libc. If not, strlcat.c provided by mk-configure is added to SRCS and declaration is provided in mkc_strlcat.h header. πŸ”₯
  • strlcpy β€” similar to strlcat. πŸ¦‹
  • strndup β€” this feature provides strndup(3) from POSIX. 🌸
  • strsep β€” this features provides strsep(3) and stresep(3) functions. πŸŽ€
  • strtoi β€” this feature provides strtoi(3) function introduced in NetBSD. ⭐
  • strtou β€” this feature provides strtoi(3) function introduced in NetBSD. ⭐
  • vis β€” this feature provides vis(3), nvis(3), svis(3), snvis(3), strvis(3), strnvis(3), strsvis(3), strsnvis(3), strvisx(3), strnvisx(3), strenvisx(3), strsvisx(3), strsnvisx(3), strsenvisx(3), strunvis(3), strnunvis(3), strunvisx(3), strnunvisx(3) and unvis(3) from NetBSD. 🌈
  • warn β€” this feature provides warn(3), warnx(3), vwarn(3) and vwarnx(3) BSD-isms. πŸ‘‘

πŸ’œ MKC_NOAUTO πŸ’œ

See MKC_CHECK_{HEADERS,FUNCLIBS,FUNCS,VARS,DEFINES,SIZEOF}. That's the whole vibe. πŸ’…

πŸ’œ MKC_NOAUTO_FUNCLIBS πŸ’œ

See MKC_CHECK_FUNCLIBS. ✨

πŸ’œ MKC_NOCACHE πŸ’œ

All results are cached unless the MKC_NOCACHE variable is set to a non-empty value. 🫢

πŸ’œ MKC_REQUIRE_BUILTINS πŸ’œ

The same as MKC_CHECK_BUILTINS, but failure is treated as a fatal error (see the configure target). 😭

πŸ’œ MKC_REQUIRE_CUSTOM πŸ’œ

The same as MKC_CHECK_CUSTOM, but failure is treated as a fatal error (see the configure target). 0 and empty value of CUSTOM.xxx means failure. πŸ’€

πŸ’œ MKC_REQUIRE_DEFINES πŸ’œ

The same as MKC_CHECK_DEFINES, but absence of the define is treated as a fatal error (see the configure target). πŸ¦‹

πŸ’œ MKC_REQUIRE_FUNCLIBS πŸ’œ

The same as MKC_CHECK_FUNCLIBS, but absence of funclib is treated as a fatal error (see the configure target). 🌸

πŸ’œ MKC_REQUIRE_FUNCS<N> πŸ’œ

The same as MKC_CHECK_FUNCS<N>, but absence of the function declaration is treated as a fatal error (see the configure target). πŸŽ€

πŸ’œ MKC_REQUIRE_HEADER_FILES πŸ’œ

The same as MKC_CHECK_HEADER_FILES, but absence of header is treated as a fatal error (see the configure target). πŸŽ€

πŸ’œ MKC_REQUIRE_HEADERS πŸ’œ

The same as MKC_CHECK_HEADERS, but absence of header is treated as a fatal error (see the configure target). πŸŽ€

πŸ’œ MKC_REQUIRE_MEMBERS πŸ’œ

The same as MKC_CHECK_MEMBERS, but absence of the member is treated as a fatal error (see the configure target). 🫢

πŸ’œ MKC_REQUIRE_PROGS πŸ’œ

The same as MKC_CHECK_PROGS, but absence of program is treated as a fatal error (see the configure target). πŸ”₯

πŸ’œ MKC_REQUIRE_PROTOTYPES πŸ’œ

The same as MKC_CHECK_PROTOTYPES, but incorrect prototype is treated as a fatal error (see the configure target). 😭

πŸ’œ MKC_REQUIRE_TYPES πŸ’œ

The same as MKC_CHECK_TYPES, but absence of the type declaration is treated as a fatal error (see the configure target). ⭐

πŸ’œ MKC_REQUIRE_VARS πŸ’œ

The same as MKC_CHECK_VARS, but absence of the variable declaration is treated as a fatal error (see the configure target). πŸ’œ

πŸ™ˆ MKC_SHOW_CACHED πŸ™ˆ

Setting it to 0 will hide

Checking ... (cached) ...

messages, that is, messages about fetching results from cache files. 🫢

🌸 MKC_SOURCE_DIR, MKC_SOURCE_DIR.<source> 🌸

Directory with sources for MKC_SOURCE_FUNCLIBS. If MKC_SOURCE_DIR.<source> is unset, MKC_SOURCE_DIR is used that defaults to ${.CURDIR}. ✨

Ex:  MKC_SOURCE_FUNCLIBS += getline
     MKC_SOURCE_DIR.getline.c = ${.CURDIR}/../missing
Res: SRCS+= ${.CURDIR}/../missing/getline.c
     HAVE_FUNCLIB.getline= 0

πŸŽ€ MKC_SOURCE_FUNCLIBS πŸŽ€

The same as MKC_CHECK_FUNCLIBS, but if <function> is absent both in the specified <library> and in libc, function.c is added to SRCS unless MKC_NOAUTO=1. πŸ’…

Ex:  MKC_SOURCE_FUNCLIBS+= getline
Res: SRCS+= getline.c
     HAVE_FUNCLIB.getline= 0

🧚 mkc.conf.mk 🧚

The same as mkc.configure.mk but mkc.init.mk is not included by mkc.conf.mk in the beginning, and CFLAGS, CPPFLAGS, LDADD and SRCS variables are not modified. Instead, internal variables MKC_CFLAGS, MKC_CPPFLAGS, MKC_LDADD and MKC_SRCS contain all changes and will be applied later. One can use this module for implementing your own "features" similar to MKC_FEATURES. 🌈

🧚 mkc_imp.scripts.mk 🧚

It's an internal include file which is included from mkc.prog.mk, mkc.lib.mk and mkc.files.mk.

⚠️ Do not use it directly! It is internal, bestie.

It provides installing and uninstalling the scripts. The following variables are provided:

  • SCRIPTS β€” a list of interpreter scripts (written in shell, awk, lua etc). These are installed like programs. <M> ✨
  • SCRIPTSDIR β€” target directory for scripts. <Iu> [${BINDIR}] πŸŽ€
  • SCRIPTSDIR_<script> β€” optional directory to install <script> to. If <script> has a form <subdir>/<filename>, SCRIPTSDIR_<subdir>_<filename> is used. <Mu> 🫢
  • SCRIPTSGRP β€” script file group. <Iu> [${BINGRP}] 🌸
  • SCRIPTSMODE β€” script file mode. <Iu> [${BINMODE}] πŸ’…
  • SCRIPTSNAME β€” the name that the above program will be installed as, if different from ${SCRIPTS}. <Mu> ⭐
  • SCRIPTSNAME_<script> β€” optional name to install <script> as. If <script> has a form <subdir>/<filename>, SCRIPTSNAME_<subdir>_<filename> is used. <Mu> πŸ¦‹
  • SCRIPTSOWN β€” script files owner. <Iu> [${BINOWN}] πŸ‘‘

🧚 mkc_imp.lua.mk 🧚

mkc_imp.lua.mk is an internal include file which is included from mkc.prog.mk and mkc.lib.mk.

⚠️ Do not use it directly. It's internal, periodt.

It provides support for the Lua programming language, i.e. building and installing Lua- and/or C-based modules. The following variables are provided:

  • LUA_CMODDIR β€” directory for compiled Lua modules written in, e.g., C or C++. It is assigned with the help of pkg-config --variable=INSTALL_CMOD lua command and can be overriden by user. <Iu> πŸ”₯
  • LUA_CMODULE β€” compiled Lua module written in, e.g., C or C++. Dot in the module name separates a dirname from basename. That is, actual .c file names are made of LUA_MODULES with dots replaced with an underscore symbol. At installation time dots are replaced with slash. For example, if LUA_CMODULES=socket.foo, then socket_foo.c will be used for compiling a module and will be installed to ${LUA_CMODDIR}/socket/foo.so. <M> 🌈
  • LUA_LMODDIR β€” directory for Lua modules written in Lua. It is assigned with the help of pkg-config --variable=INSTALL_LMOD lua command and can be overriden by user. <Iu> πŸŽ€
  • LUA_LMODULES β€” deprecated. Filenames of Lua modules. Use LUA_MODULES instead. <M> πŸ’€
  • LUA_MODULES β€” list of Lua modules to build and install. Dot in the module name separates a dirname from basename. That is, actual .lua file names are made of LUA_MODULES with dots replaced with an underscore symbol. At installation time dots are replaced with slash. For example, if LUA_MODULES=socket.foo, then socket_foo.lua will be installed to ${LUA_LMODDIR}/socket/foo.lua. <M> 🌸
  • SRCS β€” list of source files to build the LUA_CMODULE. SRCS defaults to ${LUA_CMODULE:S|.|_|g}.c. <M> ✨

🧚 mkc_imp.intexts.mk 🧚

mkc_imp.intexts.mk is an internal include file which is included from mkc.prog.mk, mkc.lib.mk and mkc.files.mk.

⚠️ Do not use it directly. It's internal, okay?

It provides conversion of <fn>.in files to <fn> by expanding the following @@ patterns: πŸ¦‹

okay so these pattern/replacement pairs are literally the matching game, and they map like this:

  • @prefix@ β†’ ${PREFIX}
  • @bindir@ β†’ ${BINDIR}
  • @mandir@ β†’ ${MANDIR}
  • @sbindir@ β†’ ${SBINDIR}
  • @libdir@ β†’ ${LIBDIR}
  • @libexecdir@ β†’ ${LIBEXECDIR}
  • @datadir@ β†’ ${DATADIR}
  • @sysconfdir@ β†’ ${SYSCONFDIR}
  • @incsdir@ β†’ ${INCSDIR}
  • @vardir@ β†’ ${VARDIR}
  • @sharedstate@ β†’ ${SHAREDSTATEDIR}

and here are the variables it hands you, bestie:

  • INFILES β€” list of files to generate. <M>
  • INSCRIPTS β€” list of scripts to generate. <M>
  • INTEXTS_REPLS β€” list of Pattern/Replacement pairs separated by space, e.g.
INTEXTS_REPLS+=   version ${VERSION}
INTEXTS_REPLS+=   author_email ${AUTHOR_EMAIL}

<M>

  • INTEXTS_SED β€” list of additional sed(1) expressions for expanding, e.g.
INTEXTS_SED+=   -e 's,0.40.3,${VERSION},g'

<M>

🧚 mkc_imp.info.mk 🧚

okay so mkc_imp.info.mk is an internal include file that gets included from mkc.prog.mk, mkc.lib.mk and mkc.files.mk. Do not use it directly! It's giving backstage-pass energy only. This module provides creation of .info files from .txi, .texi and .texinfo sources and gives you these variables:

  • INFOFLAGS β€” flags to pass to makeinfo. [] <Iu>
  • MKINFO β€” if "no", don't build or install Info documentation from Texinfo source files. <Iu> [yes]
  • TEXINFO β€” list of Texinfo source files. Info documentation will consist of single files with the extension replaced by .info. <M>

πŸŽ€ mkc_imp.man.mk πŸŽ€

mkc_imp.man.mk is an internal include file that gets included from mkc.prog.mk, mkc.lib.mk and mkc.files.mk. Do not use it directly! This module provides installation of manual pages and creation of catpages and HTML pages, and it gives you these variables:

  • HTMLDIR β€” target directory for html pages generated from man pages. <Iu> [${MANDIR}]
  • MAN β€” manual pages (usually end in .1 - .9). <M>
  • MANDIR β€” target directory for man pages. <Iu> [${PREFIX}/man]
  • MANZ β€” if not "no", compress manual pages at installation time. <Iu> [no]
  • MKCATPAGES β€” if "no", don't build or install the catman pages. <Iu> [no]
  • MKHTML β€” if "no", don't build or install the HTML man pages. <Iu> [no]
  • MKMAN β€” if "no", don't build or install the man pages, and also acts as "MKCATPAGES=no MKHTML=no". <Iu> [yes]
  • MLINKS β€” list of manual page links (using a .1 - .9 suffix). The linked-to file must come first, the linked file second, and there may be multiple pairs. The files are hard-linked. <M>
  • USETBL β€” if not "no", preprocess man pages using tbl(1) while generating cat pages. <IM> [no]

mkc_imp.links.mk is an internal include file that gets included from mkc.prog.mk, mkc.lib.mk and mkc.files.mk. Do not use it directly! This module provides creation of hard and symbolic links and gives you these variables:

  • LINKS β€” the list of binary links; should be full pathnames, the linked-to file coming first, followed by the linked file. The files are hard-linked. For example, to link ${BINDIR}/gzip and ${BINDIR}/gunzip, use:
LINKS=   ${BINDIR}/gzip ${BINDIR}/gunzip

<M>

  • SYMLINKS β€” the list of symbolic links; should be full pathnames. Syntax is identical to LINKS. Note that DESTDIR is not automatically included in the link. <M>

🌸 mkc_imp.inc.mk 🌸

mkc_imp.inc.mk is an internal include file that gets included from mkc.prog.mk, mkc.lib.mk and mkc.files.mk. Do not use it directly! This module provides installation of header files and gives you these variables:

  • INCS β€” the list of include files. <M>
  • INCSDIR β€” see mkc.init.mk.
  • INCSNAME β€” target name of the include file, if only one; same as FILESNAME, but for include files. <M>
  • INCSNAME_<file> β€” the name file <file> should be installed as, if not <file>, same as FILESNAME_<file>, but for include files. <Mu>
  • INCSSRCDIR β€” source directory for include files. This variable has an influence on CPPFLAGS (-I${INCSSRCDIR} is added) and on an installation of include files (paths in ${INCS} are relative to ${INCSSRCDIR}). <M> [.]

πŸ’… mkc.minitest.mk πŸ’…

mkc.minitest.mk is an auxiliary include file that implements a simple framework for unit tests. The idea: the application provides the target test_output and an expect.out file that contains the ideal output. mkcmake test runs mkcmake test_output and compares generated output with expect.out.

  • MKC_DIFF β€” diff(1) command for comparing expected and actual results. <Iu> [diff]
  • TEST_PREREQS β€” prerequisites for target "test". <Iu> [all]

🫢 mkc_imp.pkg-config.mk 🫢

mkc_imp.pkg-config.mk is an internal include file that gets included from mkc.prog.mk and mkc.lib.mk. Do not use it directly! This module supports dependencies controlled by the pkg-config program. As a result, CPPFLAGS and LDADD variables are modified according to "pkg-config --cflags ..." and "pkg-config --libs ...". The following variables are provided:

  • MKC_CHECK_PKGCONFIG β€” list of libraries to check, for example, glib-2.0>=2.1. Spaces around <=, >=, =, < and > are not allowed. As a result of the check, bmake's variable PKG_CONFIG.exists.<lib> is set to 1 for success or 0 for failure. Unless MKC_NOAUTO is set to 1, -DHAVE_PKGCONFIG_<LIB>=1 is also added to CPPFLAGS if <lib> was found. <LIB> is tr/a-z+.-/A-ZP__/ of <lib>. <M>
  • MKC_REQUIRE_PKGCONFIG β€” the same as MKC_REQUIRE_PKGCONFIG, but absence of library is treated as a fatal error (see configure target).
  • PCNAME.<lib> β€” on some systems several versions of the same library may be installed to different directories (for example liblua for Lua 5.1 and 5.2). In order to avoid conflicts between them, pc name is changed (for example, lua5.1 and lua5.2 instead of lua). This variable is a map from library name to pc name. <Iu> [${lib}]
  • PKG_CONFIG.exists.<lib> β€” if "1", <lib> exists, "0" otherwise. Inside <lib> the symbols <=, >=, =, < and > are replaced with _le_, _ge_, _eq_, _lt_ and _gt_ respectively. <Iu>
  • PKG_CONFIG.var.<lib>.<var> β€” variable value (pkg-config --variable=<var> <lib>). <Iu>
  • PKG_CONFIG_VARS.<lib> β€” list of variables to check for library <lib>. <M>

πŸ“ mkc_imp.pod.mk πŸ“

mkc_imp.pod.mk is an internal include file that gets included from mkc.prog.mk and mkc.lib.mk. Do not use it directly! It provides support for POD (Plain Old Documentation) markup language, i.e. conversion of POD documents to MAN pages (suffix rules: .pod.1, ... , .pod.9) and HTMLs (.pod.html). The following variables are provided:

  • POD2HTML β€” path to POD to HTML conversion utility. <Iu> [pod2html]
  • POD2HTML_FLAGS β€” flags passed to ${POD2HTML}. <Iu> []
  • POD2MAN β€” path to POD to MAN conversion utility. <Iu> [pod2man]
  • POD2MAN_FLAGS β€” flags passed to ${POD2MAN}. <Iu> [-r '' -n '${.TARGET:T:R}' -c '']

🧚 mkc_imp.dep.mk 🧚

mkc_imp.dep.mk is an internal include file that gets included from mkc.prog.mk and mkc.lib.mk. Do not use it directly! This include file contains the default targets for building .depend_${.CURDIR:T} files. It creates .d files from entries in SRCS and DPSRCS that are C, C++, or Objective C source files, and builds .depend_${PROJECTNAME} from the .d files. All other files in SRCS and all of DPSRCS will be used as dependencies for the .d files. The following variables are provided:

  • DPSRCS β€” list of source files which are needed for generating dependencies, but are not needed in ${SRCS}.
  • MKDEP_CC β€” compiler passed to mkdep(1). <Iu> [${CC}]
  • SRCS β€” the same as in mkc.prog.mk and mkc.lib.mk.

🌈 mkc_imp.foreign_autotools.mk 🌈

This module is activated if variable FOREIGN is set to "autotools" and provides support for building external projects using autotools. It also provides a recursive target mkgen for generating "configure" script, "Makefile.in" file etc. using autoreconf(1) utility. The following variables are provided:

  • AT_AUTORECONF_ARGS β€” arguments passed to autoreconf(1). <U> [-sif]
  • AT_CONFIGURE_ARGS β€” extra arguments passed to "configure" script set in addition to standard ones (--prefix, --bindir etc.). <Mu> []
  • AT_CONFIGURE_ENV β€” environment variables for "configure" script set in addition to standard ones (CC, CFLAGS etc.). <Mu> []
  • AT_MAKE β€” make(1)-like utility for the project. <Imu> [${MAKE}]
  • AT_USE_AUTOMAKE β€” if "yes", automake(1) is used. <M> [yes]
  • FSRCDIR β€” relative (to ${.CURDIR}) or absolute directory to autotools-based sources.

πŸ‘‘ mkc_imp.help.mk πŸ‘‘

This mk file implements targets help, help_subprj and help_use.

  • help_use β€” outputs the configuring options available for the project and descriptions for their values. Configuring options should be specified in the USE_VARIABLES variable described below.
  • help_subprj β€” outputs the list of subprojects (mkc.subprj.mk) and their descriptions. Subprojects are mentioned in SUBPRJ and SUBPRJ_DFLT variables. Descriptions are specified in the HELP_MSG.<subproject> variable.
  • USE_VARIABLES β€” a list of configuring variables. Let's assume that the only configuring variable is USESOMETHING and the valid values for it are: no (the default) and yes. Then developer may provide the following assignments in Makefile:
USE_VARIABLES  += USESOMETHING
USESOMETHING.descr  = "Configuring parameter SOMETHING"
USESOMETHING.0  = "no: disable feature SOMETHING"
USESOMETHING.1  = "yes: enable feature SOMETHING"

<M> [unset]

  • HELP_MSG.<subproject> β€” description for project <subproject>. <M> [unset]

πŸ’œ CROSS COMPILATION πŸ’œ

The following variables are used for compiling software using cross-tools.

  • MACHINE_GNU_PLATFORM β€” see TOOLCHAIN_PREFIX.
  • OPSYS_TARGET β€” OPSYS for target OS.
  • SYSROOT β€” root directory for headers and libraries. If set, the following variables are set to ${TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}<toolname>: AR, AS, CXX, CPP, CC, INSTALL, LD, NM, OBJCOPY, OBJDUMP, RANLIB, SIZE and STRIP. <U> []
  • TOOLDIR β€” see TOOLCHAIN_DIR.
  • TOOLCHAIN_DIR β€” directory that contains cross-toolchain. <U> [${TOOLDIR}/bin]
  • TOOLCHAIN_PREFIX β€” see SYSROOT. <U> [${MACHINE_GNU_PLATFORM}-]

πŸŽ€ ENVIRONMENT VARIABLES πŸŽ€

  • MAKECONF β€” path to mk.conf file included by mkc.*.mk files

okay final stretch bestie, we're in the endgame now ✨

πŸŽ€ FILES πŸŽ€

these are the config files mkc.init.mk goes looking for β€” no cap, it literally peeks at them:

  • /etc/mkcmake.conf β€” this one gets included by mkc.init.mk if it exists πŸ’–
  • /etc/mk.conf β€” and this one also gets included by mkc.init.mk if it exists 🫢

both are a "if it's there, we're using it" situation. if it's not there? it's not there, moving on, slay 🌸


πŸ’€ BUGS πŸ’€

okay so this is the one thing that will lowkey humble you:

the configure target (that's configure, yes literally configure) does not support parallel builds. nope. not a vibe. it simply refuses. 😭

so if you want your project built in parallel, you gotta do it in two steps like this β€” run configure first, all alone, no -j, no friends:

mkcmake configure
mkcmake -j4 all

that's it. configure does its solo main character moment, and then you let -j4 cook πŸ”₯


πŸ¦‹ SEE ALSO πŸ¦‹

go read these next, bestie β€” they're the whole friend group πŸ’…


πŸ‘‘ AUTHOR πŸ‘‘

this whole iconic situation was brought to you by:

Aleksey Cheusov <vle@gmx.net>

give them their flowers, they earned them πŸŒΈπŸ’


and that's a wrap on the whole page, bestie!! πŸŽ‰ the source/version here is MK-CONFIGURE(7) and it's dated Dec 16, 2023 β€” so go forth, configure things, and remember: configure first, -j4 after. no cap. periodt πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from