diff --git a/variables/README.md b/variables/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3e53b94ecfb001c75872c7ab618863073a4f54bc
--- /dev/null
+++ b/variables/README.md
@@ -0,0 +1,72 @@
+# Overview
+This repository is intended to centralize string data common to many builds
+(such as required compiler switches), both internal to Linden and external, on
+TeamCity and on individual dev machines.
+
+# Bash Usage
+Intended usage is to clone this repository as a sibling to the source
+directory being built, then use the bash "source" or "." commands to read
+../build-variables/convenience into your build script. This gives you
+shell variables such as
+
+LL_BUILD_RELEASE, LL_BUILD_RELWITHDEBINFO, LL_BUILD_DEBUG
+
+which are aliases for the platform-specific variables (e.g.)
+
+LL_BUILD_LINUX_RELEASE, LL_BUILD_LINUX_RELWITHDEBINFO, LL_BUILD_LINUX_DEBUG
+
+et al.
+
+If you pass a build-type argument (Release, RelWithDebInfo, Debug) when
+sourcing the convenience script, e.g.:
+
+    source ../build-variables/convenience Release
+
+then you get the additional alias LL_BUILD, which (in the example above,
+assuming you're running on Linux) is the same as LL_BUILD_LINUX_RELEASE.
+
+The convenience script also provides bash functions for removing or replacing
+individual switches from any one of those variables. See the comments in the
+script for function usage.
+
+# Other Languages
+## Variable Suite
+The convenience script sources the variables script, which provides the
+underlying suite of variables. Variable names are of the form:
+
+LL\_BUILD\_{platform}\_{buildtype}
+
+where:
+
+component | meaning
+----------|--------
+platform  | WINDOWS, DARWIN, LINUX.
+buildtype | RELEASE, RELWITHDEBINFO, DEBUG. BASE for switches common to all.
+
+These variables are in turn composed of variables that separate out
+command-line macro definitions from other kinds of compiler switches:
+
+LL\_BUILD\_{platform}\_{buildtype}\_{category}
+
+where:
+
+component | meaning
+----------|--------
+category  | MACROS, SWITCHES.
+
+These are typically aggregated into the corresponding
+LL\_BUILD\_{platform}\_{buildtype} variables:
+
+LL_BUILD_LINUX_RELEASE="$LL_BUILD_LINUX_RELEASE_SWITCHES $LL_BUILD_LINUX_RELEASE_MACROS"
+
+CMake, in particular, distinguishes between macro definitions
+([add_definitions()](https://cmake.org/cmake/help/v3.1/command/add_definitions.html))
+and other compiler switches
+([add_compile_options()](https://cmake.org/cmake/help/v3.1/command/add_compile_options.html)),
+so it may be useful to populate those CMake commands from the underlying
+_MACROS and _SWITCHES variables.
+
+## Parsing the variables file
+The variables file should be kept as simple as possible to parse, so it can be
+read from other languages than bash. Refer to the comments in that file itself
+for syntax rules.
diff --git a/variables/convenience b/variables/convenience
new file mode 100644
index 0000000000000000000000000000000000000000..432ba5c0227c8557e787846f93930ca35d59f422
--- /dev/null
+++ b/variables/convenience
@@ -0,0 +1,90 @@
+function toupper {
+    echo "$*" | tr '[a-z]' '[A-Z]'
+}
+
+# Usage:
+# switches="$(remove_switch -DPIC $LL_BUILD)"
+# It's important NOT to quote whichever compiler-arguments string you pass to
+# remove_switch (LL_BUILD in the example above), just as it's important not to
+# quote it when passing it to the compiler itself: bash must parse into
+# separate tokens.
+function remove_switch {
+    local todel="$1"
+    shift
+    local out=()
+    for sw
+    do if [ "$sw" != "$todel" ]
+       then # append $sw to out
+            out[${#out[*]}]="$sw"
+       fi
+    done
+    echo "${out[@]}"
+}
+
+# Usage:
+# switches="$(replace_switch -DPIC -DPOC $LL_BUILD)"
+# It's important NOT to quote whichever compiler-arguments string you pass to
+# replace_switch (LL_BUILD in the example above), just as it's important not to
+# quote it when passing it to the compiler itself: bash must parse into
+# separate tokens.
+function replace_switch {
+    local todel="$1"
+    local toins="$2"
+    shift
+    shift
+    echo "$toins $(remove_switch "$todel" "$@")"
+}
+
+# Bring in the variables from the 'variables' script in the same directory as
+# this script. Beware: since this script is itself sourced, its name is NOT in
+# $0, but rather in $BASH_SOURCE!
+source "$(dirname "$BASH_SOURCE")/variables"
+
+# Enumerate the known universe of buildtypes and suffixes.
+# Alternatively we could trawl the output of 'set' for variables whose name
+# matches a regexp, but this way feels more predictable.
+T=(BASE RELEASE RELWITHDEBINFO DEBUG)
+X=(_MACROS _SWITCHES "")
+
+case "$OSTYPE" in
+    cygwin)
+        p="WINDOWS"
+        ;;
+    darwin*)
+        p="DARWIN"
+        ;;
+    linux*)
+        p="LINUX"
+        ;;
+    *)
+        echo "Unrecognized platform $OSTYPE" 1>&2
+        exit 2
+        ;;
+esac
+
+# make aliases for all LL_BUILD_{platform}_{buildtype}{suffix}
+# variables that eliminate the {platform} part:
+# LL_BUILD_{buildtype}{suffix}
+# e.g. LL_BUILD_RELEASE has Release switches for current platform
+for t in "${T[@]}"
+do for x in "${X[@]}"
+   do eval LL_BUILD_$t$x=\$LL_BUILD_${p}_$t$x
+   done
+done
+
+# further, if $1 is passed as a buildtype (Release, RelWithDebInfo, Debug),
+# make aliases that eliminate the {buildtype} part: just
+# LL_BUILD{suffix}
+# e.g. if we assume 'source convenience Release', then
+# LL_BUILD has Release switches for current platform
+if [ -n "$1" ]
+then # uppercase the buildtype so that's not on our caller
+     t="$(toupper "$1")"
+     for x in "${X[@]}"
+     do eval LL_BUILD$x=\$LL_BUILD_$t$x
+     done
+fi
+
+# Since this script is designed to be sourced, explicitly delete temporary
+# variables.
+unset p T X t x
diff --git a/variables/variables b/variables/variables
new file mode 100644
index 0000000000000000000000000000000000000000..9988201ac1d2a7dd6ca92cd0080bbab8c991fcaa
--- /dev/null
+++ b/variables/variables
@@ -0,0 +1,82 @@
+# The intended use of this file is for a calling bash script to read it with
+# the "source" or "." command. However, keep the syntax as simple as possible
+# to permit other languages to parse it. Syntax rules:
+# - Ignore (of course) any line starting with #.
+# - Ignore completely empty lines.
+# - Every remaining line is a variable assignment of the form:
+#   VAR="text"
+#   Please always quote the "text" value, specifically with double-quotes.
+# - Do not use line continuation. Every assignment should be on a single line.
+# - It is permitted for "text" to embed references to other variables, using
+#   either $OTHERVAR or ${OTHERVAR} syntax. Do not use fancier bash
+#   substitutions. In particular, one variable can simply be an alias for
+#   another:
+#   VAR="$OTHERVAR"
+# These conventions should permit this file to be (for instance) imported by a
+# Python script. (See os.path.expandvars() for processing of embedded
+# variables.) However, keep the syntax strictly to the rules above to permit
+# hand-coded parsing by other languages.
+
+# This means, in particular, that when maintaining the variables in this file,
+# do not use bash fanciness to remove or replace individual switches. Instead,
+# refactor the definitions to build up the variables additively.
+# *Consumers* of this file may freely use the remove/replace functions in the
+# *companion convenience script.
+
+# Windows
+LL_BUILD_WINDOWS_BASE_MACROS="/D_SECURE_STL=0 /D_HAS_ITERATOR_DEBUGGING=0 /DWIN32 /D_WINDOWS /DLL_WINDOWS=1 /DUNICODE /D_UNICODE /DWINVER=0x0501 /D_WIN32_WINNT=0x0501 /DLL_OS_DRAGDROP_ENABLED=1 /DCARES_STATICLIB /DLIB_NDOF=1"
+LL_BUILD_WINDOWS_BASE_SWITCHES="/Zc:wchar_t- /Zi /GR /DEBUG /SAFESEH:NO /NODEFAULTLIB:LIBCMT"
+LL_BUILD_WINDOWS_BASE="$LL_BUILD_WINDOWS_BASE_SWITCHES $LL_BUILD_WINDOWS_BASE_MACROS"
+
+LL_BUILD_WINDOWS_RELEASE_MACROS="/DLL_RELEASE=1 /DLL_RELEASE_FOR_DOWNLOAD=1 /DNDEBUG $LL_BUILD_WINDOWS_BASE_MACROS"
+LL_BUILD_WINDOWS_RELEASE_SWITCHES="/MD /O2 /Ob2 /INCREMENTAL:NO /OPT:REF $LL_BUILD_WINDOWS_BASE_SWITCHES"
+LL_BUILD_WINDOWS_RELEASE="$LL_BUILD_WINDOWS_RELEASE_SWITCHES $LL_BUILD_WINDOWS_RELEASE_MACROS"
+
+LL_BUILD_WINDOWS_RELWITHDEBINFO_MACROS="/DLL_RELEASE=1 /DLL_RELEASE_WITH_DEBUG_INFO=1 /DNDEBUG $LL_BUILD_WINDOWS_BASE_MACROS"
+LL_BUILD_WINDOWS_RELWITHDEBINFO_SWITCHES="/MD /Od /Ob0 /INCREMENTAL $LL_BUILD_WINDOWS_BASE_SWITCHES"
+LL_BUILD_WINDOWS_RELWITHDEBINFO="$LL_BUILD_WINDOWS_RELWITHDEBINFO_SWITCHES $LL_BUILD_WINDOWS_RELWITHDEBINFO_MACROS"
+
+LL_BUILD_WINDOWS_DEBUG_MACROS="/D_DEBUG /DLL_DEBUG=1 /D_SCL_SECURE_NO_WARNINGS=1 $LL_BUILD_WINDOWS_BASE_MACROS"
+LL_BUILD_WINDOWS_DEBUG_SWITCHES="/MDd /Od /INCREMENTAL:NO /NODEFAULTLIB:LIBCMTD /NODEFAULTLIB:MSVCRT $LL_BUILD_WINDOWS_BASE_SWITCHES"
+LL_BUILD_WINDOWS_DEBUG="$LL_BUILD_WINDOWS_DEBUG_SWITCHES $LL_BUILD_WINDOWS_DEBUG_MACROS"
+
+LL_BUILD_WINDOWS_RELEASEOS_MACROS="/DLL_RELEASE=1 /DLL_RELEASE_FOR_DOWNLOAD=1 /DNDEBUG $LL_BUILD_WINDOWS_BASE_MACROS"
+LL_BUILD_WINDOWS_RELEASEOS_SWITCHES="/MD /O2 /Ob2 /INCREMENTAL:NO /OPT:REF $LL_BUILD_WINDOWS_BASE_SWITCHES"
+LL_BUILD_WINDOWS_RELEASEOS="$LL_BUILD_WINDOWS_RELEASE_SWITCHES $LL_BUILD_WINDOWS_RELEASE_MACROS"
+
+# Mac and Linux base macros
+LL_BUILD_POSIX_BASE_MACROS="-DLL_OS_DRAGDROP_ENABLED=1 -DCARES_STATICLIB -DLIB_NDOF=1"
+
+# Mac
+LL_BUILD_DARWIN_BASE_MACROS="-DPIC -DLL_DARWIN=1 $LL_BUILD_POSIX_BASE_MACROS"
+LL_BUILD_DARWIN_BASE_SWITCHES="-fPIC -gdwarf-2 -stdlib=libc++ -mmacosx-version-min=10.7 -iwithsysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/"
+LL_BUILD_DARWIN_BASE="$LL_BUILD_DARWIN_BASE_SWITCHES $LL_BUILD_DARWIN_BASE_MACROS"
+
+LL_BUILD_DARWIN_RELEASE_MACROS="-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG $LL_BUILD_DARWIN_BASE_MACROS"
+LL_BUILD_DARWIN_RELEASE_SWITCHES="-O3 $LL_BUILD_DARWIN_BASE_SWITCHES"
+LL_BUILD_DARWIN_RELEASE="$LL_BUILD_DARWIN_RELEASE_SWITCHES $LL_BUILD_DARWIN_RELEASE_MACROS"
+
+LL_BUILD_DARWIN_RELWITHDEBINFO_MACROS="-DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1 $LL_BUILD_DARWIN_BASE_MACROS"
+LL_BUILD_DARWIN_RELWITHDEBINFO_SWITCHES="-O0 $LL_BUILD_DARWIN_BASE_SWITCHES"
+LL_BUILD_DARWIN_RELWITHDEBINFO="$LL_BUILD_DARWIN_RELWITHDEBINFO_SWITCHES $LL_BUILD_DARWIN_RELWITHDEBINFO_MACROS"
+
+LL_BUILD_DARWIN_DEBUG_MACROS="-D_DEBUG -DLL_DEBUG=1 $LL_BUILD_DARWIN_BASE_MACROS"
+LL_BUILD_DARWIN_DEBUG_SWITCHES="-O0 $LL_BUILD_DARWIN_BASE_SWITCHES"
+LL_BUILD_DARWIN_DEBUG="$LL_BUILD_DARWIN_DEBUG_SWITCHES $LL_BUILD_DARWIN_DEBUG_MACROS"
+
+# Linux
+LL_BUILD_LINUX_BASE_MACROS="-DLL_LINUX=1 $LL_BUILD_POSIX_BASE_MACROS"
+LL_BUILD_LINUX_BASE_SWITCHES="-g -fPIC"
+LL_BUILD_LINUX_BASE="$LL_BUILD_LINUX_BASE_SWITCHES $LL_BUILD_LINUX_BASE_MACROS"
+
+LL_BUILD_LINUX_RELEASE_MACROS="$LL_BUILD_LINUX_BASE_MACROS"
+LL_BUILD_LINUX_RELEASE_SWITCHES="-O2 $LL_BUILD_LINUX_BASE_SWITCHES"
+LL_BUILD_LINUX_RELEASE="$LL_BUILD_LINUX_RELEASE_SWITCHES $LL_BUILD_LINUX_RELEASE_MACROS"
+
+LL_BUILD_LINUX_RELWITHDEBINFO_MACROS="$LL_BUILD_LINUX_BASE_MACROS"
+LL_BUILD_LINUX_RELWITHDEBINFO_SWITCHES="-O0 $LL_BUILD_LINUX_BASE_SWITCHES"
+LL_BUILD_LINUX_RELWITHDEBINFO="$LL_BUILD_LINUX_RELWITHDEBINFO_SWITCHES $LL_BUILD_LINUX_RELWITHDEBINFO_MACROS"
+
+LL_BUILD_LINUX_DEBUG_MACROS="$LL_BUILD_LINUX_BASE_MACROS"
+LL_BUILD_LINUX_DEBUG_SWITCHES="-O0 $LL_BUILD_LINUX_BASE_SWITCHES"
+LL_BUILD_LINUX_DEBUG="$LL_BUILD_LINUX_DEBUG_SWITCHES $LL_BUILD_LINUX_DEBUG_MACROS"