You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by zr...@apache.org on 2021/10/26 23:09:56 UTC

[trafficcontrol] branch master updated: Add simplicity options to pkg build system (#6274)

This is an automated email from the ASF dual-hosted git repository.

zrhoffman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new e2ba960  Add simplicity options to pkg build system (#6274)
e2ba960 is described below

commit e2ba9608713c29722174a1cef5053a77c5f3bd33
Author: ocket8888 <oc...@apache.org>
AuthorDate: Tue Oct 26 17:09:27 2021 -0600

    Add simplicity options to pkg build system (#6274)
    
    * Add simplicity options to pkg build system
    
    Adds the -S option to suppress outputting "source RPMs", the -s option
    to use simple RPM names, the -L option to suppress outputting log s in
    files, and the -h option to print help text.
    
    Previously, help text was output whenever an unknown option was passed.
    Now, passing unknown options causes pkg to exit with a failure and print
    the offending option followed by usage information, while -h causes it
    to exit with a success after printing usage information.
    
    * Add new and missing pkg options to docs
    
    * Use auto-numbering footnote for optional docker-compose dependency
    
    * Use auto-numbering footnote for default projects
    
    * Fix some projects not listed as default
    
    * Document optional projects
    
    * Use auto-numbering footnotes for native build dependency notes
    
    * Fix rendering/formatting of lists
    
    * Fix -l incorrect format and not respecting -o
    
    * Update CHANGELOG
    
    * change variable name, use src.rpm instead of .srpm
    
    * flags in help-text order
    
    * Use better subshell syntax
    
    * Fix help text indentation
    
    * Always export new variables
    
    * Revert help text to a heredoc
    
    * Order options to be sorted in en_US.utf8
    
    * Fix grove, grovetccfg, and traffic_router not respecting '-s'
    
    Also fixed grove, grovetccfg, and tomcat not outputting source RPMs
    
    * comply with en_US.utf8's weird string collation
---
 CHANGELOG.md                            |   1 +
 build/clean_build.sh                    |   7 +-
 build/functions.sh                      |  58 +++++++---
 docs/source/_static/theme_overrides.css |  64 ++++++-----
 docs/source/development/building.rst    | 182 ++++++++++++++++++++++----------
 grove/build/build_rpm.sh                |  37 ++++++-
 grove/grovetccfg/build/build_rpm.sh     |  38 ++++++-
 pkg                                     |  97 ++++++++++++-----
 traffic_router/build/build_rpm.sh       |   8 +-
 traffic_router/tomcat-rpm/build_rpm.sh  | 107 ++++++++++++-------
 10 files changed, 428 insertions(+), 171 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6b2ac2..19583e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - A new Traffic Portal server command-line option `-c` to specify a configuration file, and the ability to set `log: null` to log to stdout (consult documentation for details).
 - SANs information to the SSL key endpoint and Traffic Portal page.
 - Added definition for `heartbeat.polling.interval` for CDN Traffic Monitor config in API documentation.
+- New `pkg` script options, `-h`, `-s`, `-S`, and `-L`.
 
 ### Fixed
 - [#6197](https://github.com/apache/trafficcontrol/issues/6197) - TO `/deliveryservices/:id/routing` makes requests to all TRs instead of by CDN.
diff --git a/build/clean_build.sh b/build/clean_build.sh
index 25fe4ef..b17d4e3 100755
--- a/build/clean_build.sh
+++ b/build/clean_build.sh
@@ -15,7 +15,6 @@
 trap 'exit_code=$?; [ $exit_code -ne 0 ] && echo "Error on line ${LINENO} of ${0}"; cleanup; exit $exit_code' EXIT;
 set -o errexit -o nounset -o pipefail;
 
-
 # Fix ownership of output files
 #  $1 is file or dir with correct ownership
 #  remaining args are files/dirs to be fixed, recursively
@@ -71,5 +70,9 @@ if [ $# -eq 0 ]; then
 fi
 
 for project in "$@"; do
-	./build/build.sh "${project}" 2>&1 | tee "dist/build-${project//\//-}.log"
+	if [[ "$NO_LOG_FILES" -eq 1 ]]; then
+		./build/build.sh "${project}";
+	else
+		./build/build.sh "${project}" 2>&1 | tee "dist/build-${project//\//-}.log";
+	fi
 done
diff --git a/build/functions.sh b/build/functions.sh
index 2edcf1e..473b1a9 100755
--- a/build/functions.sh
+++ b/build/functions.sh
@@ -232,17 +232,26 @@ buildRpm() {
 		set -- "$@" --define '%_binary_payload w2.xzdio' # xz level 2 compression for binary files
 		set -o nounset; }
 
-		(cd "$RPMBUILD" && \
-			rpmbuild --define "_topdir $(pwd)" \
-				--define "traffic_control_version $TC_VERSION" \
-				--define "go_version $GO_VERSION" \
-				--define "commit $(getCommit)" \
-				--define "build_number $BUILD_NUMBER.$RHEL_VERSION" \
-				--define "_target_os $RPM_TARGET_OS" \
-				 -ba SPECS/$package.spec \
-				"$@" # variable number of arguments
-				) || \
-				 { echo "RPM BUILD FAILED: $?"; return 1; }
+		build_flags="-ba";
+		if [[ "$NO_SOURCE" -eq 1 ]]; then
+			build_flags="-bb";
+		fi
+
+		pushd "$RPMBUILD";
+
+		rpmbuild --define "_topdir $(pwd)" \
+			--define "traffic_control_version $TC_VERSION" \
+			--define "go_version $GO_VERSION" \
+			--define "commit $(getCommit)" \
+			--define "build_number $BUILD_NUMBER.$RHEL_VERSION" \
+			--define "_target_os $RPM_TARGET_OS" \
+			"$build_flags" SPECS/$package.spec \
+			"$@";
+		code=$?
+		if [[ "$code" -ne 0 ]]; then
+			echo "RPM BUILD FAILED: $code" >&2;
+			return $code;
+		fi
 
 		echo
 		echo "========================================================================================"
@@ -250,8 +259,30 @@ buildRpm() {
 		echo "========================================================================================"
 		echo
 
-		cp "$RPMBUILD/RPMS/$(uname -m)/$rpm" "$DIST/." || { echo "Could not copy $rpm to $DIST: $?"; return 1; }
-		cp "$RPMBUILD/SRPMS/$srpm" "$DIST/." || { echo "Could not copy $srpm to $DIST: $?"; return 1; }
+		rpmDest=".";
+		srcRPMDest=".";
+		if [[ "$SIMPLE" -eq 1 ]]; then
+			rpmDest="${package}.rpm";
+			srcRPMDest="${package}.src.rpm";
+		fi
+
+		cp -f "$RPMBUILD/RPMS/$(uname -m)/$rpm" "$DIST/$rpmDest";
+		code="$?";
+		if [[ "$code" -ne 0 ]]; then
+			echo "Could not copy $rpm to $DIST: $code" >&2;
+			return "$code";
+		fi
+
+		if [[ "$NO_SOURCE" -eq 1 ]]; then
+			return 0;
+		fi
+
+		cp -f "$RPMBUILD/SRPMS/$srpm" "$DIST/$srcRPMDest";
+		code="$?";
+		if [[ "$code" -ne 0 ]]; then
+			echo "Could not copy $srpm to $DIST: $code" >&2;
+			return "$code";
+		fi
 	done
 }
 
@@ -349,4 +380,3 @@ verify_and_set_go_version() {
 		return 1
 	fi
 }
-
diff --git a/docs/source/_static/theme_overrides.css b/docs/source/_static/theme_overrides.css
index af3f5c5..ebdf46e 100644
--- a/docs/source/_static/theme_overrides.css
+++ b/docs/source/_static/theme_overrides.css
@@ -19,27 +19,25 @@
 
 /* override table width restrictions */
 .wy-table-responsive table td, .wy-table-responsive table th {
-    /* !important prevents the common CSS stylesheets from
-       overriding this as on RTD they are loaded after this stylesheet */
-    white-space: normal !important;
+	/*
+	 * !important prevents the common CSS stylesheets from
+	 * overriding this as on RTD they are loaded after this stylesheet
+	 */
+	white-space: normal !important;
 	word-wrap: break-word !important;
 }
 
-/*.wy-table-responsive {
-    overflow: visible !important;
-}
-*/
 .wy-side-nav-search {
-  background-color: #000000;
+	background-color: #000000;
 }
 
 .adminition-title {
-  background-color: #404040;
+	background-color: #404040;
 }
 .wy-alert.wy-alert-info, .rst-content .note, .rst-content .wy-alert-info.attention, .rst-content .wy-alert-info.caution, .rst-content
 .wy-alert-info.danger, .rst-content .wy-alert-info.error, .rst-content .wy-alert-info.hint, .rst-content .wy-alert-info.important,
 .rst-content .wy-alert-info.tip, .rst-content .wy-alert-info.warning, .rst-content .seealso, .rst-content .wy-alert-info.admonition-todo {
-  background: #dde0e2;
+	background: #dde0e2;
 }
 
 .wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title,
@@ -51,41 +49,53 @@
 .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content
 .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title,
 .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title {
-  background: #404040;
+	background: #404040;
 }
 
 .section {
-  margin-top: 20px;
+	margin-top: 20px;
 }
 .wy-nav-content {
-  padding:1.618em 3.236em;
-  height:100%;
-  /*max-width:1100px;*/
-  max-width: none;
-  /*margin:auto;*/
+	padding: 1.618em 3.236em;
+	height: 100%;
+	max-width: none;
 }
 
-/*   Darker Table borders (they're hard to see imo)   */
+/* Darker Table borders (they're hard to see imo) */
 .wy-table-responsive > table, .wy-table-responsive > table th, .wy-table-responsive > table td {
-  border-color: #989898 !important;
+	border-color: #989898 !important;
 }
 
 abbr {
-  cursor: help;
+	cursor: help;
 }
 
-/* On small screens, content can get cut off. It *should* squeeze as much as it can, but some tables
-   will refuse to squeeze beyodn a certain point. */
+/*
+ * On small screens, content can get cut off. It *should* squeeze as much as it
+ * can, but some tables will refuse to squeeze beyond a certain point.
+ */
 html, html body {
-  overflow-x: auto;
+	overflow-x: auto;
 }
 
 .same {
-    font-weight: 700;
-    color: #050;
+	font-weight: 700;
+	color: #050;
 }
 
 .none {
-    font-weight: 700;
-    color: #800;
+	font-weight: 700;
+	color: #800;
+}
+
+/*
+ * Some versions of the sphinx-rtd theme are making lists unstyled, which makes
+ * it hard to tell something's a list.
+ */
+ul, ol, ul > li, ol > li {
+	list-style: unset;
+}
+
+ul > li > p, ol > li > p {
+	margin: 0;
 }
diff --git a/docs/source/development/building.rst b/docs/source/development/building.rst
index eaa79c3..0553e18 100644
--- a/docs/source/development/building.rst
+++ b/docs/source/development/building.rst
@@ -37,45 +37,113 @@ This is the easiest way to build all the components of Traffic Control; all requ
 Requirements
 ------------
 - `Docker <https://docs.docker.com/engine/installation/>`_
-- `Docker Compose <https://docs.docker.com/compose/install/>`_\ [1]_
+- `Docker Compose <https://docs.docker.com/compose/install/>`_\ [#compose-optional]_
 
 
 Usage
 -----
 ``./pkg [options] [projects]``
 
-.. note:: The ``pkg`` script often needs to be run as ``sudo``, as certain privileges are required to run Docker containers
-
 Options
+"""""""
+
+.. option:: -7
+
+	Build RPMs targeting CentOS 7.
+
+	.. versionchanged:: ATCv6.0.0
+
+		Previously, :option:`-7` was implicit if not given. As of ATC version 6.0.0, this is no longer the case, and :option:`-8` is implicit instead.
+
+.. option:: -8
+
+	Build RPMs targeting CentOS 8 (default).
+
+	.. versionchanged:: ATCv6.0.0
+
+		Previously, :option:`-7` was implicit if not given. As of ATC version 6.0.0, this is no longer the case, and :option:`-8` is implicit instead.
+
+.. option:: a
+
+	Build all projects, including optional ones.
+
+.. option:: -b
+
+	Build builder Docker images before building projects.
+
+.. option:: -d
+
+	Disable compiler optimizations for debugging.
+
+.. option:: -f FILE
+
+	Use ``FILE`` instead of the default Docker-Compose file (``./infrastructure/docker/build/docker-compose.yml``).
+
+.. option:: -h
+
+	Print help message and exit.
+
+	.. versionadded:: ATCv6.1.0
+
+.. option:: -l
+
+	List available projects.
+
+	.. caution:: This lists only the projects that are built by default if none are specified, not *all* projects that can be built. See :issue:`6272`.
+
+.. option:: -L
+
+	Don't write logs to files - respects output levels on STDERR/STDOUT as set by :option:`-q`/:option:`-v`.
+
+.. option:: -o
+
+	Build from the optional list. Same as passing :option:`-f` with the option-argument ``./infrastructure/docker/build/docker-compose-opt.yml``.
+
+.. option:: -p
+
+	Pull builder Docker images, do not build them (default).
+
+.. option:: -q
+
+	Quiet mode. Suppresses output (default).
+
+.. option:: -s
+
+	Simple output filenames - e.g. ``traffic_ops.rpm`` instead of ``traffic_ops-6.1.0-11637.ec9ff6a6.el8.x86_64.rpm``.
+
+	.. versionadded:: ATCv6.1.0
+
+.. option:: -S
+
+	Skip building "source RPMs".
+
+	.. versionadded:: ATCv6.1.0
+
+.. option:: -v
+
+	Verbose mode. Lists all build output.
+
+	.. versionadded:: ATCv6.1.0
 
--7    Build RPMs targeting CentOS 7 (default)
--8    Build RPMs targeting CentOS 8
--b    Build builder Docker images before building projects
--d    Disable compiler optimizations for debugging.
--l    List available projects.
--p    Pull builder Docker images, do not build them (default)
--q    Quiet mode. Supresses output. (default)
--v    Verbose mode. Lists all build output.
 
 If present, ``projects`` should be one or more project names. When no specific project or project list is given the default projects will be built. Valid projects:
 
-- docs
-- grove_build\ [2]_
-- grovetccfg_build
-- source\ [2]_
-- traffic_monitor_build\ [2]_
-- traffic_ops_build\ [2]_
-- cache-config_build\ [2]_
-- traffic_portal_build\ [2]_
-- traffic_router_build\ [2]_
-- traffic_stats_build\ [2]_
-- weasel
+- ats\ [#optional-project]_
+- docs\ [#default-project]_
+- fakeorigin_build\ [#optional-project]_
+- grove_build\ [#default-project]_
+- grovetccfg_build\ [#default-project]_
+- source\ [#default-project]_
+- traffic_monitor_build\ [#default-project]_
+- traffic_ops_build\ [#default-project]_
+- cache-config_build\ [#default-project]_
+- traffic_portal_build\ [#default-project]_
+- traffic_router_build\ [#default-project]_
+- traffic_stats_build\ [#default-project]_
+- weasel\ [#default-project]_
 
 Output :file:`{component}-{version}.rpm` files, build logs and source tarballs will be output to the ``dist/`` directory at the root of the Traffic Control repository directory.
 
-.. [1] This is optional, but recommended. If a ``docker-compose`` executable is not available the ``pkg`` script will automatically download and run it using a container. This is noticeably slower than running it natively.
-.. [2] This is a default project, which will be built if ``pkg`` is run with no ``projects`` argument
-
 .. _build-with-dc:
 
 Build Using ``docker-compose``
@@ -97,29 +165,29 @@ Install the Dependencies
 
 .. table:: Build dependencies for Traffic Control
 
-	+------------------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
-	|                                    | Common dependencies | :ref:`dev-traffic-monitor` | :ref:`dev-traffic-ops` | :ref:`dev-traffic-portal` | :ref:`dev-traffic-router` | :ref:`dev-traffic-stats` | Grove    | Grove TC Config (grovetccfg) | :ref:`Docs <docs-guide>` |
-	+====================================+=====================+============================+========================+===========================+===========================+==========================+==========+==============================+==========================+
-	| macOS (homebrew_)\ [3]_            | - rpm               | - go                       | - go                   | - npm                     | - maven                   | - go                     | - go     | - go                         | - python3                |
-	|                                    |                     |                            |                        | - grunt-cli               |                           |                          |          |                              |                          |
-	+------------------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
-	| CentOS/Red Hat/Fedora (yum_)\ [4]_ | - git               |                            |                        | - epel-release            | - java-1.8.0-openjdk      |                          |          |                              | - python3-devel          |
-	|                                    | - rpm-build         |                            |                        | - npm                     | - maven                   |                          |          |                              | - gcc                    |
-	|                                    | - rsync             |                            |                        | - nodejs-grunt-cli        |                           |                          |          |                              | - make                   |
-	+------------------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
-	| Arch Linux (pacman_)               | - git               | - go                       | - go                   | - npm                     | - jdk8-openjdk            | - go                     | - go     | - go                         | - python-pip             |
-	|                                    | - rpm-tools         |                            |                        | - grunt-cli               | - maven                   |                          |          |                              | - python-sphinx          |
-	|                                    | - diff              |                            |                        |                           |                           |                          |          |                              | - make                   |
-	|                                    | - rsync             |                            |                        |                           |                           |                          |          |                              |                          |
-	+------------------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
-	| Windows (cygwin_)\ [5]_            | - git               |                            |                        |                           | - curl                    |                          |          |                              |                          |
-	|                                    | - rpm-build         |                            |                        |                           |                           |                          |          |                              |                          |
-	|                                    | - rsync             |                            |                        |                           |                           |                          |          |                              |                          |
-	+------------------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
-	| Windows (chocolatey_)\ [5]_        |                     | - golang                   | - golang               | - nodejs                  | - openjdk8                | - golang                 | - golang | - golang                     | - python                 |
-	|                                    |                     |                            |                        |                           | - maven                   |                          |          |                              | - pip                    |
-	|                                    |                     |                            |                        |                           |                           |                          |          |                              | - make                   |
-	+------------------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
+	+----------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
+	| OS/Package Manager         | Common dependencies | :ref:`dev-traffic-monitor` | :ref:`dev-traffic-ops` | :ref:`dev-traffic-portal` | :ref:`dev-traffic-router` | :ref:`dev-traffic-stats` | Grove    | Grove TC Config (grovetccfg) | :ref:`Docs <docs-guide>` |
+	+============================+=====================+============================+========================+===========================+===========================+==========================+==========+==============================+==========================+
+	| macOS\ [#mac-jdk]_         | - rpm               | - go                       | - go                   | - npm                     | - maven                   | - go                     | - go     | - go                         | - python3                |
+	| (homebrew_)                |                     |                            |                        | - grunt-cli               |                           |                          |          |                              |                          |
+	+----------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
+	| CentOS\ [#centos-go]_,     | - git               |                            |                        | - epel-release            | - java-1.8.0-openjdk      |                          |          |                              | - python3-devel          |
+	| Red Hat,                   | - rpm-build         |                            |                        | - npm                     | - maven                   |                          |          |                              | - gcc                    |
+	| Fedora                     | - rsync             |                            |                        | - nodejs-grunt-cli        |                           |                          |          |                              | - make                   |
+	| (yum_)                     |                     |                            |                        |                           |                           |                          |          |                              |                          |
+	+----------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
+	| Arch Linux,                | - git               | - go                       | - go                   | - npm                     | - jdk8-openjdk            | - go                     | - go     | - go                         | - python-pip             |
+	| Manjaro                    | - rpm-tools         |                            |                        | - grunt-cli               | - maven                   |                          |          |                              | - python-sphinx          |
+	| (pacman_)                  | - diff              |                            |                        |                           |                           |                          |          |                              | - make                   |
+	+----------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
+	| Windows                    | - git               |                            |                        |                           | - curl                    |                          |          |                              |                          |
+	| (cygwin_)\ [#windeps]_     | - rpm-build         |                            |                        |                           |                           |                          |          |                              |                          |
+	|                            | - rsync             |                            |                        |                           |                           |                          |          |                              |                          |
+	+----------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
+	| Windows                    |                     | - golang                   | - golang               | - nodejs                  | - openjdk8                | - golang                 | - golang | - golang                     | - python                 |
+	| (chocolatey_)\ [#windeps]_ |                     |                            |                        |                           | - maven                   |                          |          |                              | - pip                    |
+	|                            |                     |                            |                        |                           |                           |                          |          |                              | - make                   |
+	+----------------------------+---------------------+----------------------------+------------------------+---------------------------+---------------------------+--------------------------+----------+------------------------------+--------------------------+
 
 .. _homebrew:   https://brew.sh/
 .. _yum:        https://wiki.centos.org/PackageManagement/Yum
@@ -127,20 +195,13 @@ Install the Dependencies
 .. _cygwin:     https://cygwin.com/
 .. _chocolatey: https://chocolatey.org/
 
-.. [3] If you are on macOS, you additionally need to :ref:`dev-tr-mac-jdk`.
-
-.. [4] If you are on CentOS, you need to `download Go directly <https://golang.org/dl/>`_ instead of using a package manager in order to get the latest Go version. For most users, the desired architecture is AMD64/x86_64.
-
-.. [5] If you are on Windows, you need to install both the Cygwin packages and the Chocolatey packages in order to build the Apache Traffic Control RPMs natively.
-
 .. |AdoptOpenJDK instructions| replace:: add the AdoptOpenJDK tap and install the ``adoptopenjdk8`` cask
 .. _AdoptOpenJDK instructions: https://github.com/AdoptOpenJDK/homebrew-openjdk#other-versions
 
 After installing the packages using your platform's package manager,
 
-	- Install the :ref:`global NPM packages <dev-tp-global-npm>` to build Traffic Portal.
-
-	- Install the Python 3 modules used to :ref:`build the documentation <docs-build>`.
+- Install the :ref:`global NPM packages <dev-tp-global-npm>` to build Traffic Portal.
+- Install the Python 3 modules used to :ref:`build the documentation <docs-build>`.
 
 Run ``build/clean_build.sh`` directly
 -------------------------------------
@@ -177,3 +238,10 @@ Each Traffic Control component can be individually built, and the instructions f
 Building This Documentation
 ---------------------------
 See instructions for :ref:`building the documentation <docs-build>`.
+
+.. [#compose-optional] This is optional, but recommended. If a ``docker-compose`` executable is not available the ``pkg`` script will automatically download and run it using a container. This is noticeably slower than running it natively.
+.. [#optional-project] This project is "optional", which means that it cannot be built unless :option:`-o` is given.
+.. [#default-project] This is a default project, which will be built if ``pkg`` is run with no ``projects`` argument
+.. [#mac-jdk] If you are on macOS, you additionally need to :ref:`dev-tr-mac-jdk`.
+.. [#centos-go] If you are on CentOS, you need to `download Go directly <https://golang.org/dl/>`_ instead of using a package manager in order to get the latest Go version. For most users, the desired architecture is AMD64/x86_64.
+.. [#windeps] If you are on Windows, you need to install **both** the Cygwin packages and the Chocolatey packages in order to build the Apache Traffic Control RPMs natively.
diff --git a/grove/build/build_rpm.sh b/grove/build/build_rpm.sh
index 1406cb7..a9ecf5b 100755
--- a/grove/build/build_rpm.sh
+++ b/grove/build/build_rpm.sh
@@ -43,6 +43,7 @@ checkGroveEnvironment() {
 	RPMBUILD="${GROVE_DIR}/rpmbuild"
 	DIST="${TC_DIR}/dist"
 	RPM="${PACKAGE}-${GROVE_VERSION}-${BUILD_NUMBER}.${RHEL_VERSION}.x86_64.rpm"
+	SRPM="${PACKAGE}-${GROVE_VERSION}-${BUILD_NUMBER}.${RHEL_VERSION}.src.rpm"
 	GOOS="${GOOS:-linux}"
 	RPM_TARGET_OS="${RPM_TARGET_OS:-$GOOS}"
 	export GROVE_DIR GROVE_VERSION PACKAGE BUILD_NUMBER RPMBUILD DIST RPM GOOS RPM_TARGET_OS
@@ -98,6 +99,12 @@ buildRpmGrove() {
 		trap give_spec_back EXIT
 	fi
 
+	build_flags="-ba";
+	if [[ "$NO_SOURCE" -eq 1 ]]; then
+		build_flags="-bb";
+	fi
+
+
 	# build RPM with xz level 2 compression
 	rpmbuild \
 		--define "_topdir $RPMBUILD" \
@@ -106,12 +113,36 @@ buildRpmGrove() {
 		--define "_target_os ${RPM_TARGET_OS}" \
 		--define '%_source_payload w2.xzdio' \
 		--define '%_binary_payload w2.xzdio' \
-		-ba build/grove.spec ||
+		$build_flags build/grove.spec ||
 		{ echo "rpmbuild failed: $?" >&2; return 1; }
 
+	rpmDest=".";
+	srcRPMDest=".";
+	if [[ "$SIMPLE" -eq 1 ]]; then
+		rpmDest="grove.rpm";
+		srcRPMDest="grove.src.rpm";
+	fi
+
 	# copy build RPM to .
-	[ -e "$DIST" ] || mkdir -p "$DIST"
-	cp "${RPMBUILD}/RPMS/x86_64/${RPM}" "$DIST"
+	[ -d "$DIST" ] || mkdir -p "$DIST";
+
+	cp -f "$RPMBUILD/RPMS/$(uname -m)/${RPM}" "$DIST/$rpmDest";
+	code="$?";
+	if [[ "$code" -ne 0 ]]; then
+		echo "Could not copy $rpm to $DIST: $code" >&2;
+		return "$code";
+	fi
+
+	if [[ "$NO_SOURCE" -eq 1 ]]; then
+		return 0;
+	fi
+
+	cp -f "$RPMBUILD/SRPMS/${SRPM}" "$DIST/$srcRPMDest";
+	code="$?";
+	if [[ "$code" -ne 0 ]]; then
+		echo "Could not copy $srpm to $DIST: $code" >&2;
+		return "$code";
+	fi
 }
 
 importFunctions
diff --git a/grove/grovetccfg/build/build_rpm.sh b/grove/grovetccfg/build/build_rpm.sh
index 58f45a9..e1f2755 100755
--- a/grove/grovetccfg/build/build_rpm.sh
+++ b/grove/grovetccfg/build/build_rpm.sh
@@ -43,6 +43,7 @@ checkGroveEnvironment() {
 	RPMBUILD="${GROVE_DIR}/rpmbuild"
 	DIST="${TC_DIR}/dist"
 	RPM="${PACKAGE}-${GROVE_VERSION}-${BUILD_NUMBER}.${RHEL_VERSION}.x86_64.rpm"
+	SRPM="${PACKAGE}-${GROVE_VERSION}-${BUILD_NUMBER}.${RHEL_VERSION}.src.rpm"
 	GOOS="${GOOS:-linux}"
 	RPM_TARGET_OS="${RPM_TARGET_OS:-$GOOS}"
 	export GROVETC_DIR GROVE_DIR GROVE_VERSION PACKAGE BUILD_NUMBER RPMBUILD DIST RPM GOOS RPM_TARGET_OS
@@ -99,6 +100,12 @@ buildRpmGrove() {
 		trap give_spec_back EXIT
 	fi
 
+	build_flags="-ba";
+	if [[ "$NO_SOURCE" -eq 1 ]]; then
+		build_flags="-bb";
+	fi
+
+
 	# build RPM with xz level 2 compression
 	rpmbuild \
 		--define "_topdir $RPMBUILD" \
@@ -107,12 +114,37 @@ buildRpmGrove() {
 		--define "_target_os ${RPM_TARGET_OS}" \
 		--define '%_source_payload w2.xzdio' \
 		--define '%_binary_payload w2.xzdio' \
-		-ba build/${PACKAGE}.spec ||
+		$build_flags build/${PACKAGE}.spec ||
 		{ echo "rpmbuild failed: $?" >&2; return 1; }
 
+
+	rpmDest=".";
+	srcRPMDest=".";
+	if [[ "$SIMPLE" -eq 1 ]]; then
+		rpmDest="grovetccfg.rpm";
+		srcRPMDest="grovetccfg.src.rpm";
+	fi
+
 	# copy build RPM to .
-	[ -e "$DIST" ] || mkdir -p "$DIST"
-	cp "${RPMBUILD}/RPMS/x86_64/${RPM}" "$DIST"
+	[ -d "$DIST" ] || mkdir -p "$DIST";
+
+	cp -f "$RPMBUILD/RPMS/$(uname -m)/${RPM}" "$DIST/$rpmDest";
+	code="$?";
+	if [[ "$code" -ne 0 ]]; then
+		echo "Could not copy $rpm to $DIST: $code" >&2;
+		return "$code";
+	fi
+
+	if [[ "$NO_SOURCE" -eq 1 ]]; then
+		return 0;
+	fi
+
+	cp -f "$RPMBUILD/SRPMS/${SRPM}" "$DIST/$srcRPMDest";
+	code="$?";
+	if [[ "$code" -ne 0 ]]; then
+		echo "Could not copy $srpm to $DIST: $code" >&2;
+		return "$code";
+	fi
 }
 
 importFunctions
diff --git a/pkg b/pkg
index 2d147cd..b84e69d 100755
--- a/pkg
+++ b/pkg
@@ -89,29 +89,16 @@ debug=0
 quiet=0
 all=0
 build_images=0
-while getopts :?78abdf:lopqv opt; do
+NO_LOG_FILES=0
+NO_SOURCE=0
+SIMPLE=0
+list=0
+failure=0
+print_help=0
+while getopts h78abdf:lopqvsSL opt; do
 	case $opt in
 		\?)
-			PROJECTS=`$SELF -l | sed "s/^/  - /"`
-			<<-HELP_TEXT cat
-			Usage: $SELF [options] [projects]
-			  -7           Build RPMs targeting CentOS 7
-			  -8           Build RPMs targeting CentOS 8 (default)
-			  -a           Build all projects, including optional ones.
-			  -b           Build builder Docker images before building projects
-			  -d           Disable compiler optimizations for debugging.
-			  -f <file>    Use <file> as the docker-compose. Default: $COMPOSE_FILE
-			  -l           List available projects.
-			  -o           Build from the optional list. Same as -f "$COMPOSE_FILE_OPT"
-			  -p           Pull builder Docker images, do not build them (default)
-			  -q           Quiet mode. Supresses output. (default)
-			  -v           Verbose mode. Lists all build output.
-
-			If no projects are listed, all projects will be packaged.
-			Valid projects:
-			$PROJECTS
-			HELP_TEXT
-			exit 0
+			failure=1;
 			;;
 		7)
 			RHEL_VERSION=7
@@ -135,12 +122,17 @@ while getopts :?78abdf:lopqv opt; do
 		f)
 			COMPOSE_FILE="$OPTARG"
 			;;
+		h)
+			print_help=1;
+			;;
+		L)
+			NO_LOG_FILES=1
+			;;
 		l)
-			"${COMPOSECMD[@]}" -f $COMPOSE_FILE config --services
-			exit $?
+			list=1;
 			;;
 		o)
-			COMPOSE_FILE="$COMPOSE_FILE_OPT"
+			COMPOSE_FILE="$COMPOSE_FILE_OPT";
 			;;
 		p)
 			build_images=0
@@ -152,16 +144,68 @@ while getopts :?78abdf:lopqv opt; do
 		v)
 			verbose=1
 			;;
+		s)
+			SIMPLE=1
+			;;
+		S)
+			NO_SOURCE=1
+			;;
 	esac
 done
 
+PROJECTS="$("${COMPOSECMD[@]}" -f $COMPOSE_FILE config --services)"
+HELP_TEXT="$(cat <<HELP_TEXT
+Usage: $SELF [options] [projects]
+  -7           Build RPMs targeting CentOS 7
+  -8           Build RPMs targeting CentOS 8 (default)
+  -a           Build all projects, including optional ones.
+  -b           Build builder Docker images before building projects
+  -d           Disable compiler optimizations for debugging.
+  -f <file>    Use <file> as the docker-compose. Default: $COMPOSE_FILE
+  -h           Print help message and exit
+  -L           Don't write logs to files - respects output levels on stderr/stdout as set by -q/-v
+  -l           List available projects.
+  -o           Build from the optional list. Same as -f "$COMPOSE_FILE_OPT"
+  -p           Pull builder Docker images, do not build them (default)
+  -q           Quiet mode. Supresses output. (default)
+  -s           Simple output filenames - e.g. traffic_ops.rpm instead of traffic_ops-6.1.0-11637.ec9ff6a6.el8.x86_64.rpm
+  -S           Skip building "source rpms"
+  -v           Verbose mode. Lists all build output.
+
+If no projects are listed, all projects will be packaged.
+Valid projects:
+$(echo "$PROJECTS" | sed "s/^/  - /")
+HELP_TEXT
+)";
+
+if [[ "$failure" -ne 0 ]]; then
+	echo "$HELP_TEXT" >&2;
+	exit "$failure";
+fi
+
+if [[ "$print_help" -eq 1 ]]; then
+	echo "$HELP_TEXT";
+	exit 0;
+fi
+
+if [[ "$list" -eq 1 ]]; then
+	echo "$PROJECTS";
+	exit 0;
+fi
+
 shift $((OPTIND-1))
 
 # Mark RHEL_VERSION for export
-export RHEL_VERSION
+export RHEL_VERSION;
 if [[ -n "$RHEL_VERSION" ]]; then
-	RUN_OPTIONS+=(-e RHEL_VERSION)
+	RUN_OPTIONS+=(-e RHEL_VERSION);
 fi
+export SIMPLE;
+export NO_SOURCE;
+export NO_LOG_FILES;
+RUN_OPTIONS+=(-e SIMPLE);
+RUN_OPTIONS+=(-e NO_SOURCE);
+RUN_OPTIONS+=(-e NO_LOG_FILES);
 
 # If no specific packages are listed, or -a is used, run them all.
 if (( ! "$#" || "$all" == 1 )); then
@@ -172,7 +216,6 @@ fi
 mkdir -p dist
 
 # Build each project in turn.
-failure=0
 badproj=""
 while (( "$#" )); do
 	echo Building $1.
diff --git a/traffic_router/build/build_rpm.sh b/traffic_router/build/build_rpm.sh
index 1592b28..5f2ab96 100755
--- a/traffic_router/build/build_rpm.sh
+++ b/traffic_router/build/build_rpm.sh
@@ -56,7 +56,13 @@ buildRpmTrafficRouter () {
 	echo
 	mkdir -p "$DIST" || { echo "Could not create $DIST: $?"; return 1; }
 
-	cp "$rpm" "$DIST/." || { echo "Could not copy $rpm to $DIST: $?"; return 1; }
+	rpmDest="."
+	if [[ "$SIMPLE" -eq 1 ]]; then
+		rpmDest="traffic_router.rpm";
+	fi
+
+
+	cp -f "$rpm" "$DIST/$rpmDest" || { echo "Could not copy $rpm to $DIST: $?"; return 1; }
 
 }
 
diff --git a/traffic_router/tomcat-rpm/build_rpm.sh b/traffic_router/tomcat-rpm/build_rpm.sh
index 4b3a22c..e79c93e 100755
--- a/traffic_router/tomcat-rpm/build_rpm.sh
+++ b/traffic_router/tomcat-rpm/build_rpm.sh
@@ -42,6 +42,7 @@ checkEnvironment() {
 	# Forcing BUILD NUMBER to 1 since this is outside the tree and related to Tomcat Release
 	export BUILD_NUMBER=1
 	export RPM="${PACKAGE}-${TOMCAT_VERSION}.${TOMCAT_RELEASE}-${BUILD_NUMBER}.${RHEL_VERSION}.noarch.rpm"
+	export SRPM="${PACKAGE}-${TOMCAT_VERSION}.${TOMCAT_RELEASE}-${BUILD_NUMBER}.${RHEL_VERSION}.src.rpm"
 
 
 	echo "=================================================="
@@ -55,21 +56,21 @@ checkEnvironment() {
 
 # ---------------------------------------
 initBuildArea() {
-				echo "Initializing the build area."
-				(mkdir -p "$RPMBUILD"
-				 cd "$RPMBUILD"
-				 mkdir -p SPECS SOURCES RPMS SRPMS BUILD BUILDROOT) || { echo "Could not create $RPMBUILD: $?"; return 1; }
-				export VERSION=$TOMCAT_VERSION
-				export RELEASE=$TOMCAT_RELEASE
+	echo "Initializing the build area."
+	(mkdir -p "$RPMBUILD"
+	 cd "$RPMBUILD"
+	 mkdir -p SPECS SOURCES RPMS SRPMS BUILD BUILDROOT) || { echo "Could not create $RPMBUILD: $?"; return 1; }
+	export VERSION=$TOMCAT_VERSION
+	export RELEASE=$TOMCAT_RELEASE
 
-				echo "Downloading Tomcat $VERSION.$RELEASE..."
-				curl -fo "${RPMBUILD}/SOURCES/apache-tomcat-${VERSION}.${RELEASE}.tar.gz" "https://archive.apache.org/dist/tomcat/tomcat-${VERSION%.*}/v${VERSION}.${RELEASE}/bin/apache-tomcat-${VERSION}.${RELEASE}.tar.gz" || \
-				{ echo "Could not download Tomcat $VERSION.$RELEASE: $?"; exit 1; }
+	echo "Downloading Tomcat $VERSION.$RELEASE..."
+	curl -fo "${RPMBUILD}/SOURCES/apache-tomcat-${VERSION}.${RELEASE}.tar.gz" "https://archive.apache.org/dist/tomcat/tomcat-${VERSION%.*}/v${VERSION}.${RELEASE}/bin/apache-tomcat-${VERSION}.${RELEASE}.tar.gz" || \
+	{ echo "Could not download Tomcat $VERSION.$RELEASE: $?"; exit 1; }
 
-				cp "$TR_DIR/tomcat-rpm/tomcat.service" "$RPMBUILD/SOURCES/" || { echo "Could not copy source files: $?"; exit 1; }
-				cp "$TR_DIR/tomcat-rpm/tomcat.spec" "$RPMBUILD/SPECS/" || { echo "Could not copy spec files: $?"; exit 1; }
+	cp "$TR_DIR/tomcat-rpm/tomcat.service" "$RPMBUILD/SOURCES/" || { echo "Could not copy source files: $?"; exit 1; }
+	cp "$TR_DIR/tomcat-rpm/tomcat.spec" "$RPMBUILD/SPECS/" || { echo "Could not copy spec files: $?"; exit 1; }
 
-				echo "The build area has been initialized."
+	echo "The build area has been initialized."
 }
 
 #----------------------------------------
@@ -79,31 +80,63 @@ buildRpmTomcat () {
 }
 
 buildRpmForEl () {
-				echo "Building the rpm for ${RHEL_VERSION}."
-
-				cd "$RPMBUILD"
-				# build RPM with xz level 2 compression
-				rpmbuild --define "_topdir $(pwd)" \
-								 --define "build_number $BUILD_NUMBER.$RHEL_VERSION" \
-								 --define "tomcat_version $TOMCAT_VERSION.$TOMCAT_RELEASE" \
-								 --define "_target_os ${RPM_TARGET_OS}" \
-								 --define '%_source_payload w2.xzdio' \
-								 --define '%_binary_payload w2.xzdio' \
-								 -ba SPECS/$SPEC_FILE_NAME ||
-								 { echo "RPM BUILD FAILED: $?"; exit 1; }
-				local rpm
-				rpm="$(find ./RPMS -name "$RPM")"
-				if [ -z "$rpm" ]; then
-								echo "Could not find rpm file $RPM in $(pwd)"
-								exit 1;
-				fi
-				echo "========================================================================================"
-				echo "RPM BUILD SUCCEEDED, See $DIST/$RPM for the newly built rpm."
-				echo "========================================================================================"
-				echo
-				mkdir -p "$DIST" || { echo "Could not create $DIST: $?"; exit 1; }
-
-				cp "$rpm" "$DIST/." || { echo "Could not copy $rpm to $DIST: $?"; exit 1; }
+	echo "Building the rpm for ${RHEL_VERSION}."
+
+	cd "$RPMBUILD"
+
+	build_flags="-ba";
+	if [[ "$NO_SOURCE" -eq 1 ]]; then
+		build_flags="-bb";
+	fi
+
+
+	# build RPM with xz level 2 compression
+	rpmbuild --define "_topdir $(pwd)" \
+		--define "build_number $BUILD_NUMBER.$RHEL_VERSION" \
+		--define "tomcat_version $TOMCAT_VERSION.$TOMCAT_RELEASE" \
+		--define "_target_os ${RPM_TARGET_OS}" \
+		--define '%_source_payload w2.xzdio' \
+		--define '%_binary_payload w2.xzdio' \
+		$build_flags SPECS/$SPEC_FILE_NAME ||
+		{ echo "RPM BUILD FAILED: $?"; exit 1; }
+	local rpm
+	local srpm
+	rpm="$(find ./RPMS -name "$RPM")"
+	srpm="$(find ./SRPMS -name "$SRPM")";
+	if [ -z "$rpm" ]; then
+		echo "Could not find rpm file $RPM in $(pwd)"
+		exit 1;
+	fi
+	echo "========================================================================================"
+	echo "RPM BUILD SUCCEEDED, See $DIST/$RPM for the newly built rpm."
+	echo "========================================================================================"
+	echo
+	mkdir -p "$DIST" || { echo "Could not create $DIST: $?"; exit 1; }
+
+	rpmDest="."
+	srcRPMDest="."
+	if [[ "$SIMPLE" -eq 1 ]]; then
+		rpmDest="tomcat.rpm";
+		srcRPMDest="tomcat.src.rpm";
+	fi
+
+	cp -f "$RPMBUILD/RPMS/noarch/${RPM}" "$DIST/$rpmDest";
+	code="$?";
+	if [[ "$code" -ne 0 ]]; then
+		echo "Could not copy $rpm to $DIST: $code" >&2;
+		return "$code";
+	fi
+
+	if [[ "$NO_SOURCE" -eq 1 ]]; then
+		return 0;
+	fi
+
+	cp -f "$RPMBUILD/SRPMS/${SRPM}" "$DIST/$srcRPMDest";
+	code="$?";
+	if [[ "$code" -ne 0 ]]; then
+		echo "Could not copy $srpm to $DIST: $code" >&2;
+		return "$code";
+	fi
 }
 
 checkEnvironment -i curl