author Mike Sullivan <Mike.Sullivan@Oracle.COM>
Thu, 08 Oct 2015 23:00:32 -0700
changeset 4929 29020dc0c404
parent 4428 21fcfd647301
child 5125 34cc580c62c2
permissions -rw-r--r--
Added tag s12-85 for changeset 264d4a0eb386

This is a guide to explain various useful variables in Userland component
Makefiles.  To distinguish these from the Makefile(s) that are part of each
component distribution, the latter will be referred to as native Makefiles.

The following are the basics that just about every Makefile should have.
* COMPONENT_NAME is typically a short name (e.g., vim).
* COMPONENT_VERSION is typically numbers separated by dots (e.g. 7.3).
* COMPONENT_SRC is where the archive is extracted.  A common value for this is
* COMPONENT_PROJECT_URL is the general web site for the component.
* COMPONENT_ARCHIVE is the base name of the archive to be downloaded.  A common
  value for this is "$(COMPONENT_SRC).tar.gz".
* COMPONENT_ARCHIVE_HASH is typically "sha256:" followed by the first output
  field of `sha256sum $(COMPONENT_ARCHIVE)`.
* COMPONENT_ARCHIVE_URL is where the archive can be downloaded from.  This is
  typically constructed from $(COMPONENT_PROJECT_URL) and $(COMPONENT_ARCHIVE).
* COMPONENT_SIG_URL is the URL where the PGP signature for $(COMPONENT_ARCHIVE)
  can be found.  This can be used in addition to the hash in
  $(COMPONENT_ARCHIVE_HASH) to verify the correctness of the archive.  If
  COMPONENT_SIG_URL is present, then COMPONENT_ARCHIVE_HASH needn't be, but its
  presence is strongly encouraged to ensure that the archive contents don't
  change silently.  Note that when merging, because
  $WS/tools/.gnupg/pubring.gpg is a binary file, you will have to choose
  the parent or child version.  Pick one, then run:
	for cset in $(hg log -r 'parents()' -T '{node} '); do
		hg cat -r $cset $WS/tools/.gnupg/pubring.gpg | \
			gpg2 --homedir=$WS/tools/.gnupg --import;
  before you 'hg commit' your merge.
* COMPONENT_BUGDB is the lower-case rendering of the BugDB cat/subcat.
* REQUIRED_PACKAGES is a list of packages required to build or run the
  component and its tests.

* GIT_REPO can be used in place of COMPONENT_ARCHIVE_URL to pull the component
  source from the GIT repository referenced in the value.
* GIT_REV is the tag or changeset that you wish to pull from GIT.

* HG_REPO can be used in place of COMPONENT_ARCHIVE_URL to pull the component
  source from the Mercurial repository referenced in the value.
* HG_REV is the tag or changeset that you wish to pull from Mercurial.

* SVN_REPO can be used in place of COMPONENT_ARCHIVE_URL to pull the component
  source from the Subversion repository referenced in the value.
* SVN_REV is the tag or changeset that you wish to pull from Subversion.

When using a source code management system as the canonical source for a
component, the build automatically generates a source archive for the
component by pulling the source from the SCM and creating a tarball from
the pulled source.  This allows us to automatically store a copy of the
canonical source that we build from in our source archive cache and not
continually hammer on the component's SCM repo.  The source archive name
is automatically generated from the COMPONENT_NAME, COMPONENT_VERSION,
and {GIT|HG|SVN}_REV values.  Also, the source is archived and unpacked
in a directory using these values.   You should also define a hash for
this tarball in your Makefile similar to what you do with downloaded
source archives.

These two are both initialized in make-rules/ rather than any
component-level Makefile, but are frequently referenced from the latter.
* COMPONENT_DIR is the top-level directory of the given component in question.

Additional pre/post configure, build, or install actions can be specified in
a component Makefile by setting them in one of the following macros.  None of
these have default values.  These are mostly used for miscellaneous set-up or
clean-up tweaks as their names suggest.
* COMPONENT_PRE_CONFIGURE_ACTION is used by several components to clone a
  source directory.

If component specific make targets need to be used for build or install or
test, they can be specified via the following.
* COMPONENT_BUILD_TARGETS is not usually set because the default target of most
  open source software is the equivalent of a 'build' target.  This needs to be
  set when building the software requires a different target than the default.
  You should not override make macros here, but in COMPONENT_BUILD_ARGS.
* COMPONENT_INSTALL_TARGETS has a default value of "install".  Very few
  components need to alter this.
* COMPONENT_TEST_TARGETS has a default value of "check".  Several components
  need to set this to "test".

* COMPONENT_BUILD_ARGS is probably the mostly useful variable here for solving
  subtle build issues.  When you need to override a MACRO set in the native
  Makefile of a component, do so by adding something like:
  Quoting is often important because values with white-space can be split up,
  yielding the wrong results.
* COMPONENT_BUILD_ENV is for when you just need to override things in the
  calling environment, like PATH.
* COMPONENT_INSTALL_ARGS is mainly used for altering target directories.
* COMPONENT_INSTALL_ENV is mainly used for altering target directories.
* COMPONENT_PUBLISH_ENV is so far only used to work around Python issues when
  used by "pkgdepend generate", though the variable may be extended in the
  future for general "gmake publish" usage.
* COMPONENT_TEST_ARGS is little used.
* COMPONENT_TEST_ENV is mainly used for altering PATH and friends.

If your component needs to do some kind of cleanup after a "gmake test" run,
such as kill processes after doing a "gmake test" run, then this can be done

If you have created master test results file(s) for your component in the
COMPONENT_TEST_RESULTS_DIR directory, then in order to successfully compare
your test results against that master results file, you might need to
normalize some of the test output lines. This is done via a set of regular
expressions that are applied to the test results. There are some global
default ones in the COMPONENT_TEST_TRANSFORMS definition in,
but your component Makefile might have to += some more for specific transforms
that need to be applied to the test output for just this component.

* SKIP_TEST_AT_TOP_LEVEL inclusion of this variable in a component Makefile
  will cause that component's tests to be skipped when running "gmake test"
  at the top level.  It's often used for excluding long-running tests 
  that may slow down comprehensive component testing.  

* COMPONENT_POST_UNPACK_ACTION is for making minor alterations to the unpacked
  source directory before any patching has taken place.  It should almost never
  be used.
* COMPONENT_PREP_ACTION is used to make alterations to the unpacked and patched
  source.  It should be used with care.

* CONFIGURE_DEFAULT_DIRS should be "yes" or "no".  A value of "yes" (the
  default) will trigger the following being passed to CONFIGURE_OPTIONS as
  parameters to corresponding options.
  * CONFIGURE_BINDIR is the value for the --bindir= option.
  * CONFIGURE_LIBDIR is the value for the --libdir= option.
  * CONFIGURE_MANDIR is the value for the --mandir= option.
  * CONFIGURE_SBINDIR is the value for the --sbindir= option.
* CONFIGURE_ENV is mainly used for passing CFLAGS and other common Makefile
  variables to configure.  When should this be used as opposed to
  to tell configure how to build the software using CONFIGURE_OPTIONS.  But
  sometimes you need to pass values in via the calling environment.  On rare
  occasions, you still need to do things like override MACRO settings in the
  generated Makefiles with COMPONENT_BUILD_ARGS.
* CONFIGURE_LOCALEDIR is a cousin of the other *DIR variables above, but
  rarely used and hence not triggered by CONFIGURE_DEFAULT_DIRS.
* CONFIGURE_OPTIONS is extremely useful, possibly our most used "add-on"
  variable, for passing various options to configure.  These tend to vary per
  component, but --enable-foo and --disable-foo for various values of foo are
  quite common.
* CONFIGURE_PREFIX is the prefix for the various *DIR variables above.  Its
  default is "/usr"; set it if some other value (e.g., "/usr/gnu") is needed.
* CONFIGURE_SCRIPT should be set if the default "$(SOURCE_DIR)/configure" is
  unsuitable for whatever reason.

* studio_OPT has a default value of "-xO4".  Occasional bugs in the optimizer
  have been found which have required altering this to "-xO3".  There are also
  studio_OPT.$(MACH).$(BITS) versions of this available if greater specificity
  is needed.

* TPNO is the Third Party number (i.e., a numeric value): the License
  Technology from the Product Lifecycle Suite tool.  This should be used
  in the common case when there is just one TPNO for a component.  We
  recommend that this be near the top of any Makefile, just below the
  various COMPONENT_foo definitions.
* TPNO_foo is for the rare case (~3% of components) when a component has
  more than one TPNO.  Each one should have a separate short but descriptive
  name substituted for "foo".  This likewise should be near the top of any
  Makefile, just below the various COMPONENT_foo definitions, and it must
  also be before the inclusion of .


Now switching from explaining the function of specific variables to a more
general discussion about how to use them to solve problems.  One method that
has served time and again is adding a level of indirection.  For example,
when Python 3 came along, we decided to build it 64-bit only, which meant
its various modules also needed to be built 64-bit only.  But many of them
had BUILD_32_and_64 in their native Makefile.  So how to tweak that macro
to do one thing for Python 2.x but another for 3.x?  JBeck spent an entire
day trying various combinations that seemed right, but none of them worked.
Then Norm pointed out that changing PYTHON_VERSIONS from "3.4 2.7 2.6" to
$(PYTHON3_VERSIONS) and $(PYTHON2_VERSIONS) which in turn were "3.4" and
"2.7 2.6" would do the trick.  I.e., adding a level of indirection solved
the problem, as it allowed $(PYTHON_VERSIONS) to be used to specify 64-bit
macros but $(PYTHON2_VERSIONS) to specify 32-bit macros.  There are many
other places where constructs like this are used.