123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- $OpenBSD: README.internals,v 1.14 2016/04/26 17:35:35 naddy Exp $
- Copyright (C) 2011-2012 Marc Espie <espie@openbsd.org>
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- This file is *not* user documentation of the *mk files. The full user
- documentation is available as manpages such as bsd.port.mk(5)
- There are comments in bsd.port.mk but this file is already too long,
- so I finally decided to put the design notes in a separate file.
- Most of this is not for the faint of heart.
- "Imagination could conceive almost anything in connexion with this place."
- (H.P. Lovecraft, At the Mountains of Madness)
- Some design principles
- ----------------------
- - all variables and targets prefixed with _ are for internal use.
- It may be that some other tools reuse them, but that's generally following
- the same guidelines: no user serviceable parts inside (and you should always
- ask ME about it, since I'm liable to change these with very little notice).
- This is an attempt to avoid exposing too many knobs, and a clear distinction
- between "supported" stuff, and "you're on your own, if you abuse this, bad
- things will happen".
- - most variables will always be defined, even with an empty value. This avoids
- stupid .if defined(TESTS).
- - bsd.port.mk has a strict separation between variable definitions (at top)
- and target definitions (right after the
- ###
- ### end of variable setup. Only targets now
- ###
- comment). This is because of make's "lazy" way to evaluate things:
- constructs in shell-lines get evaluated very very late. But all
- targets (such as ${_WRKDIR_COOKIE}) get evaluated when they're
- encountered. There was some significant effort in the early days
- when I took bsd.port.mk over to achieve that separation. Be very
- careful with Makefile.inc and modules, since those get included at
- a very specific location in the Makefile. They should mostly define
- variables. Makefile.inc is included very early so that it can
- override about anything it should be able to (but then, nothing is
- already defined except for read-only variables / global user-tweakable
- defaults). Modules is included a little bit later...
- - a lot of the code is done through shell fragments. All of these are
- internal and prefixed with _. This is done for speed and compactness (forking
- an external shell would be very slow, and a total nightmare with respect
- to parameter passing). These often communicate through internal shell
- variables with well-defined names.
- - the infrastructure tries very hard to have real files (as far as possible)
- attached to most targets: "make package" points to the actual pkgfile(s)
- being generated. There's a whole section of the makefile devoted to
- targets generated from the distfiles devoted to fetch and fetch-all
- (see the section around _EVERYTHING for variable definition, and the
- # Separate target for each file fetch-all will retrieve
- for the actual targets). Apart from that, once a port starts building,
- targets "without" an actual file will generate a cookie under WRKDIR or
- some subdir of it (see all the _COOKIE* definitions). Of particular interest
- are dependencies, where the cookie file is generated depending on the
- name of the dependency: that's the infamous
- .for _i in ${_DEPLIST}
- ${WRKDIR}/.dep-${_i:C,>=,ge-,g:C,<=,le-,g:C,<,lt-,g:C,>,gt-,g:C,\*,ANY,g:C,[|:/=],-,g}: ${_WRKDIR_COOKIE}
- loop. The reason for that complexity is that this avoids rechecking
- dependencies while working on a port, since only the new stuff will need
- evaluation...
- In general, make works really bad when you write
- phony-target1: phony-target2
- @do_some_shit
- as phony targets are always out-of-date, and thus you will always do_some_shit.
- - a lot of computations are very expensive, so there are shortcuts all over
- the place whenever a variable is empty, especially for dependency computation.
- Introspection
- -------------
- There's a lot of stuff in the infrastructure which is there only for
- introspection purposes: show, show-all, print-plist-*, dump-vars,
- *-dir-depends, print-update-signature.
- They allow external tools to interrogate the ports tree and get most
- information from it. dpb and sqlports rely very heavily on it.
- Significant work has been done to achieve better MI. The MULTI_PACKAGES
- code now assumes you will define MULTI_PACKAGES *independently of the
- architecture*, annotate subpackage with ONLY_FOR_ARCHS-sub if appropriate,
- then .include <bsd.port.arch.mk> (which was split off the main file
- specifically for that purpose), and rely on BUILD_PACKAGES for building.
- Shell tricks and constructs
- ---------------------------
- - IFS is your friend: echo "a:b:c"| while IFS=: read a b c
- will split things along any character without requiring external commands
- such as cut.
- - don't run test for checking variable values. Rather:
- case "$$subdir" in *,*) ... ;; *) ... ;; esac
- is entirely internal
- - the shell has booleans. Set variables to true/false to achieve boolean
- conditions. Note that those are usually built-ins, and hence even faster
- than you would think.
- - () forks a subshell. If you need to syntactally keep a list of commands
- together, "{ cmd1; cmd2; }" is the way to do it.
- - use trap to clean up at the end of a command. That's mostly used for
- caching stuff (depfile and cache), but also for the locking mechanism.
- - exec is often used for tail recursion: it replaces the shell with the
- executed command. BUT beware of pending traps, as you will lose them.
- - all of make commands are executed under -e. Thus, it's deadly to fail
- without a test around it. In the end, you might end up with:
- if ( eval $$toset exec ${MAKE} subupdate ); then
- this forks a subshell to avoid the unpleasantness of -e, then execs the
- resulting command to avoid piling up an extra process.
- Make vs. Shell
- --------------
- There are at least *4* kind of variables in those files:
- - internal shell variables
- - environment variables
- - make variables set on the command line
- - make variables set within a makefile
- Note that make variables set on the command line ARE set in stone: it's very
- difficult to change them from within the Makefile, and they will override
- mostly anything you can do. They also appear in the environment.
- Thus, a lot of make thingies, such as FLAVOR and SUBPACKAGE must be set in
- the environment because make will run into subdirs and requires them to
- be changeable.
- Also, note that stuff set within Makefiles is not exported to the environment,
- you have to be explicit and set them when you run a command.
- When things get ambiguous, This document uses $$var for a shell variable,
- ${VAR} for a variable set in make, and VAR for an environment variables.
- pkgpath.mk
- ----------
- Named that way because it mostly deals with pkgpath parsing, but in reality,
- it's mostly a lift-up from the common parts between bsd.port.mk and
- bsd.port.subdir.mk (no reason for a name change so late in the game)
- fragments and common shell variables
- ------------------------------------
- _pflavor_fragment (in pkgpath.mk)
- takes $$subdir as a pkgpath parameter.
- will parse it into a $$dir and $$toset variables, perform a cd $$dir
- so that eval $$toset ${MAKE} gets you into that
- dependency (this will set PKGPATH, FLAVOR, SUBPACKAGE accordingly)
- depending on $$_fullpath (true/false), will consider the absence
- of flavor to be an empty flavor (e.g. $$toset contains FLAVOR='' )
- or to be the default flavor (e.g. unset FLAVOR)
- takes ${PORTSDIR_PATH} into account
- succeeds if the dependency is correct and the directory is found.
- Otherwise will emit an error message that ends with $$extra_msg.
- _flavor_fragment (in pkgpath.mk)
- calls ${_pflavor_fragment} after imposing $$_fullpath=false. e.g., for
- actual dependencies.
- _depfile_fragment (in pkgpath.mk)
- sets _DEPENDS_FILE to a temporary file in the environment if it's
- not already set. Set a trap to remove it on end.
- _DEPENDS_FILE is used by the *dir-depends and show-run-depends targets
- to not go thru the same directory twice. Beware of setting it
- "too globally", since it prevents directory walking from happening
- twice.
- _cache_fragment (in pkgpath.mk)
- sets _DEPENDS_CACHE to a temporary directory in the environment
- if it's not already set. Set a trap to remove it on end.
- _DEPENDS_CACHE is used to store library lists in _libs2cache.
- pkg_create(1) also knows about it and use it to store plists.
- the ${SUDO} part in the trap is because some of the caching happens
- during ${SUDO} pkg_create.
- XXX also sets PKGPATH, as it reduces drastically the number of
- PKGPATH=... needed in bsd.port.mk
- _read_spec/_parse_spec (in bsd.port.mk)
- normally used in a pattern like:
- ${_emit_run_depends}|while ${_read_spec}; do
- ${_parse_spec};
- ...
- done
- takes specs, one per line, sets $$pkg $$subdir $$target,
- and calls ${_flavor_fragment} to cd to the correct dir
- and set $$toset. Note that this takes "processed" specs:
- transformation of pkgpath>=0.0 -> STEM->=0.0:pkgpath must have
- already happened upfront (which happens in place for all
- *DEPENDS variables).
- This sets $$d to the spec being processed, which is probably a
- bad variable name...
- _emit_run_depends/_emit_lib_depends (in bsd.port.mk)
- writes out lists of specs suitable for ${_parse_spec}/${_read_spec}.
- _compute_default (in bsd.port.mk)
- comes after ${_pflavor_fragment}, and obtains information from
- the dependent port: sets $$default to the default pkgname,
- $$pkgspec to the default pkgspec (see PKGSPEC), and $$pkgpath
- to the actual pkgpath, when default flavors and subpackages are
- taken into account (hence suitable for FULLPATH=Yes/$$_fullpath=true
- Used alone when we only need $$default, as ${_complete_pkgspec} is
- slightly more expensive.
- _complete_pkgspec (in bsd.port.mk)
- comes after ${_pflavor_fragment}, obtains information from
- the dependent port through ${_compute_default}, then make sure
- $$pkg has the correct value.
- _libs2cache (in bsd.port.mk)
- requires properly set dependency information obtained through
- ${_flavor_fragment} (often through ${_parse_spec}).
- assumes ${_depcache_fragment} has been called, either directly,
- or from an upper level target.
- If not already available, secure the library list from the
- dependency and store it in a file under _DEPENDS_CACHE.
- Sets $$cached_libs to the file name.
- Locking
- -------
- Done thru _DO_LOCK and _SIMPLE_LOCK mostly. Most user-visible targets
- redirect through
- ${_DO_LOCK}; make _internal-$@
- as soon as locking is used (which is the default these days).
- The locking mechanism carefully maintains the _LOCK_HELD environment variable
- so that dependencies can relock themselves (yeah, it looks strange, but this
- happens !).
- _SIMPLE_LOCK only exists to provide separate locking targets for fetch: it
- assumes $$lock has been set to an appropriate lock file name.
- Internal targets are:
- _internal-clean _internal-package-only _internal-run-depends
- _internal-runlib-depends _internal-runwantlib-depends _internal-package
- _internal-build-depends _internal-buildlib-depends
- _internal-buildwantlib-depends _internal-test-depends
- _internal-prepare _internal-depends _internal-fetch-all
- _internal-fetch _internal-all _internal-build _internal-checksum
- _internal-configure _internal-deinstall _internal-extract _internal-fake
- _internal-patch _internal-plist _internal-test _internal-subpackage
- _internal-subupdate _internal-uninstall _internal-update
- _internal-update-or-install _internal-update-or-install-all
- _internal-update-plist _internal-distpatch
- (yeah, that's a lot).
- So, if you type "make", it will do
- make build -> lock && make _internal-all
- then make _internal-all will normally run thru
- _internal-fetch _internal-extract _internal-patch _internal-build
- without ever releasing the lock, thus preventing anything else to sneak
- in and break the build.
- The difference between _internal-package and _internal-package-only is only
- due to BULK=Yes, which has to happen exactly once after a user-level target
- that involves packaging is finished.
- Misc
- ----
- - Modules inclusion is done through a separate modules.port.mk to handle
- recursion: modules may trigger the inclusion of other modules, thus
- modules.port.mk will re-include itself until the whole list is done.
- - MULTI_PACKAGES and SUBPACKAGE always get set to a non-empty value:
- if MULTI_PACKAGES is not set, it ends up as MULTI_PACKAGES=- and
- SUBPACKAGE=-. This does make loops over all subpackages simpler, e.g.,
- .for _s in ${MULTI_PACKAGES} since make doesn't do anything if the list
- is empty...
- As a result, most subpackage-dependent variables end up being used as their
- "true" VAR- form in the case of a port without multi-packages.
- Exception: FULLPKGNAME needs some specific code for the !multi-packages case.
- There's also a special case for the PKGDIR stuff, which isn't suffixed with '-'
- in the non multi-package case.
- Also, dump-vars distinguishes the !multi case.
- Note that there are a few checks for empty SUBPACKAGE, these allow the whole
- bsd.port.mk file to parse, so that we end up with an actual user error
- message instead of some weird internal error.
- Dependency variables
- --------------------
- Old legacy dependency styles are gone, so the compat code went away.
- The code has to deal with BUILD_DEPENDS, LIB_DEPENDS, RUN_DEPENDS,
- TEST_DEPENDS, WANTLIB and RUN_DEPENDS-* LIB_DEPENDS-*, WANTLIB-*
- There is obviously completely different treatment for WANTLIB* and
- *DEPENDS*. Also, BUILD* stuff gets to inherit from LIB_DEPENDS* stripped
- of inter-dependencies, and RUN-s stuff must have LIB_DEPENDS* from
- inter-dependencies.
- First, the framework substitutes in place constructs like
- pkgpath>=version into STEM->=version:pkgpath
- Then it accumulates dependency into build-time dependencies:
- - collect LIB_DEPENDS and LIB_DEPENDS-* as _BUILDLIB_DEPENDS
- - collect WANTLIB and WANTLIB-* as _BUILDWANTLIB
- (strip any interdependencies)
- Symetrically:
- - define _LIB4-* as the interdependencies in LIB_DEPENDS-*
- - define _LIB4 as the full list of all _LIB4-*
- - define _BUILD_DEPLIST, _RUN_DEPLIST, _TEST_DEPLIST, _BUILDLIB_DEPLIST,
- _RUNLIB_DEPLIST as the dependency lists relevant to the SUBPACKAGE being
- built (not set if NO_DEPENDS is Yes !)
- This accumulates as _DEPLIST, which is the full list of all specs in every
- dependency.
- *2 and *3 have the :configure/:patch/:build modifiers stripped:
- _BUILD_DEP2: BUILD_DEPENDS + _BUILDLIB_DEPENDS
- _BUILD_DEP3: BUILD_DEPENDS
- _BUILD_DEP3-*: _BUILD_DEP3
- _RUN_DEP2: RUN_DEPENDS (+LIB_DEPENDS-s if shared)
- _RUN_DEP3: RUN_DEPEND
- _RUN_DEP3-*: RUN_DEPENDS-* (+LIB_DEPENDS-* if shared)
- _LIB_DEP3: (LIB_DEPENDS-s if shared)
- _LIB_DEP3-*: (LIB_DEPENDS-* if shared)
- _TEST_DEP2: TEST_DEPENDS
- _TEST_DEP3: TEST_DEPENDS
- _DEPBUILDLIBS: _BUILDWANTLIB
- _DEPRUNLIBS: WANTLIB-s
- _BUILD_DEP is the _BUILD_DEP2 paths, without the specs
- _RUN_DEP is the _RUN_DEP2 paths, without the specs
- _TEST_DEP is the _TEST_DEP2 paths, without the specs
- e.g., *2 is "all the shit relevant to the port at hand", *3 is
- "only the shit directly relevant to the port with subpackages,
- or everything pertinent to THAT given subpackage".
- This gets converted into cookies relevant to each dependency
- _DEPBUILDLIBS -> _DEPBUILDLIBSPECS_COOKIES as .spec-$i
- _DEPRUNLIBS -> _DEPRUNLIBSPECS_COOKIES as .spec-$i
- _DEPBUILDWANTLIB_COOKIE as .buildwantlibs
- _DEPRUNWANTLIB_COOKIE as .runwantlibs-s
- Then there are rules for each dependency: a loop over _DEPLIST
- for each spec, and code to build both _DEP*WANTLIB_COOKIEs
- There's also some dependency in handling in
- *wantlib-args, lib-depends-args and run-depends-args.
- _DEPENDS_TARGET: used to be DEPENDS_TARGET, and visible, but not documented
- for years, and it can be set internally. Ports normally install their
- dependencies, with the exception of "make reinstall", and "make update".
- _FETCH_MAKEFILE: where to put the output of "fetch-makefile", by default
- stdout, but overridden from the main Makefile.
- _SHSCRIPT: prepend to a shell script in the infrastructure, e.g.,
- ${_SHSCRIPT}/update-patches
- _PERLSCRIPT: likewise for perl scripts.
- _ALL_VARIABLES _ALL_VARIABLES_INDEXED _ALL_VARIABLES_PER_ARCH:
- stuff to dump in dump-vars. First is "simple" variable, second one
- will depend on the subpackage, and for last one, must iterate
- over arches to get all relevant information.
- _BAD_LICENSING:
- note that the PERMIT_* variables are defined for subpackages as soon as
- the main variables are defined, so it's enough to check the normal variables.
- _lt_libs:
- derived from SHARED_LIBRARIES explicitly for libtool
- _FLAVOR_EXT2: FLAVOR_EXT with pseudo-flavors included
- _PKG_ARGS: list of stuff to append to base PKG_ARGS-sub based on a lot of
- internal choices.
- _README_DIR: location for the pkg-readmes, no user serviceable parts inside.
- _MASTER: dependencies may be confusing, so set _MASTER to know where we come
- from when patching/configuring only.
- _DEPENDENCY_STACK: pkg_add -a to avoid manually installed packages.
- _CHECK_DEPENDS: save all depends prior to tweaking them, just in case.
- _PERL_FIX_SHAR make visible ?
- TODO document:
- MAKE_JOBS
- PARALLEL_BUILD
- PARALLEL_INSTALL
- XAUTHORITY for interactive tests
- fishy: FLAVORS tests ?
- fishy: TEST_STATUS_IGNORE
- fishy:
- GZIP
- GZIP_CMD
- M4
- STRIP
- uninstall ? deinstall
- Todo: kill PORT_LD_LIBRARY_PATH
- Document: all recursive targets
|