Bug 481815: makefile hooks required for signing executable files, installer packages, and mars. r=ted
authorChris AtLee <catlee@mozilla.com>
Wed, 07 Dec 2011 17:06:52 -0500
changeset 84203 6b60ebe2cae4
parent 84202 fa06ce52a09e
child 84204 1e0a2b58599c
push id114
push userffxbld
push date2012-03-09 01:01 +0000
treeherdermozilla-release@c081ebf13261 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs481815
milestone11.0a1
Bug 481815: makefile hooks required for signing executable files, installer packages, and mars. r=ted
browser/build.mk
browser/installer/Makefile.in
client.mk
toolkit/locales/l10n.mk
toolkit/mozapps/installer/packager.mk
toolkit/mozapps/installer/signing.mk
toolkit/mozapps/installer/windows/nsis/makensis.mk
tools/update-packaging/Makefile.in
--- a/browser/build.mk
+++ b/browser/build.mk
@@ -75,16 +75,19 @@ installer:
 	@$(MAKE) -C browser/installer installer
 
 package:
 	@$(MAKE) -C browser/installer
 
 package-compare:
 	@$(MAKE) -C browser/installer package-compare
 
+stage-package:
+	@$(MAKE) -C browser/installer stage-package
+
 install::
 	@$(MAKE) -C browser/installer install
 
 clean::
 	@$(MAKE) -C browser/installer clean
 
 distclean::
 	@$(MAKE) -C browser/installer distclean
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -109,16 +109,17 @@ MOZ_PKG_MAC_EXTRA=--symlink "/Applicatio
 endif
 
 ifndef LIBXUL_SDK
 INSTALL_SDK = 1
 endif
 
 GENERATE_CACHE = 1
 
+include $(topsrcdir)/toolkit/mozapps/installer/signing.mk
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
 
 ifeq (bundle, $(MOZ_FS_LAYOUT))
 BINPATH = $(_BINPATH)
 DEFINES += -DAPPNAME=$(_APPNAME)
 else
 # Every other platform just winds up in dist/bin
 BINPATH = bin
--- a/client.mk
+++ b/client.mk
@@ -205,17 +205,17 @@ everything: clean build
 ifdef MOZ_OBJDIR
   PGO_OBJDIR = $(MOZ_OBJDIR)
 else
   PGO_OBJDIR := $(TOPSRCDIR)
 endif
 
 profiledbuild::
 	$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1
-	$(MAKE) -C $(PGO_OBJDIR) package
+	$(MAKE) -C $(PGO_OBJDIR) stage-package
 	OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT)
 	$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
 	$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1
 
 #####################################################
 # Build date unification
 
 ifdef MOZ_UNIFY_BDATE
--- a/toolkit/locales/l10n.mk
+++ b/toolkit/locales/l10n.mk
@@ -91,25 +91,26 @@ DEFINES += \
 	$(NULL)
 
 
 clobber-%:
 	$(RM) -rf $(DIST)/xpi-stage/locale-$*
 
 
 PACKAGER_NO_LIBS = 1
-include $(MOZILLA_DIR)/toolkit/mozapps/installer/packager.mk
-
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 STAGEDIST = $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR)/$(_APPNAME)/Contents/MacOS
 else
 STAGEDIST = $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR)
 endif
 
+include $(topsrcdir)/toolkit/mozapps/installer/signing.mk
+include $(MOZILLA_DIR)/toolkit/mozapps/installer/packager.mk
+
 $(STAGEDIST): AB_CD:=en-US
 $(STAGEDIST): UNPACKAGE=$(call ESCAPE_SPACE,$(ZIP_IN))
 $(STAGEDIST): $(call ESCAPE_SPACE,$(ZIP_IN))
 # only mac needs to remove the parent of STAGEDIST...
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 	$(RM) -r -v $(DIST)/l10n-stage
 else
 # ... and windows doesn't like removing STAGEDIST itself, remove all children
@@ -170,16 +171,17 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 endif
 endif
 ifdef MOZ_OMNIJAR
 	@(cd $(STAGEDIST) && $(UNPACK_OMNIJAR))
 endif
 	$(MAKE) clobber-zip AB_CD=$(AB_CD)
 	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
 	mv -f "$(DIST)/l10n-stage/$(PACKAGE)" "$(ZIP_OUT)"
+	if test -f "$(DIST)/l10n-stage/$(PACKAGE).asc"; then mv -f "$(DIST)/l10n-stage/$(PACKAGE).asc" "$(ZIP_OUT).asc"; fi
 
 repackage-zip-%: $(STAGEDIST)
 	@$(MAKE) repackage-zip AB_CD=$* ZIP_IN="$(ZIP_IN)"
 
 APP_DEFINES = $(firstword $(wildcard $(LOCALE_SRCDIR)/defines.inc) \
                           $(srcdir)/en-US/defines.inc)
 TK_DEFINES = $(firstword \
    $(wildcard $(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/defines.inc) \
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -112,17 +112,17 @@ JSSHELL_BINS += \
   $(DIST)/bin/$(LIB_PREFIX)plds4$(DLL_SUFFIX) \
   $(DIST)/bin/$(LIB_PREFIX)plc4$(DLL_SUFFIX) \
   $(NULL)
 endif
 endif # MOZ_NATIVE_NSPR
 MAKE_JSSHELL  = $(ZIP) -9j $(PKG_JSSHELL) $(JSSHELL_BINS)
 endif # LIBXUL_SDK
 
-MAKE_PACKAGE	= $(error What is a $(MOZ_PKG_FORMAT) package format?);
+PREPARE_PACKAGE	= $(error What is a $(MOZ_PKG_FORMAT) package format?);
 _ABS_DIST = $(call core_abspath,$(DIST))
 JARLOG_DIR = $(call core_abspath,$(DEPTH)/jarlog/)
 JARLOG_DIR_AB_CD = $(JARLOG_DIR)/$(AB_CD)
 
 CREATE_FINAL_TAR = $(TAR) -c --owner=0 --group=0 --numeric-owner \
   --mode="go-w" -f
 UNPACK_TAR       = tar -xf-
 
@@ -140,16 +140,20 @@ MAKE_SDK = $(CREATE_FINAL_TAR) - $(MOZ_A
 endif
 ifeq ($(MOZ_PKG_FORMAT),BZ2)
 PKG_SUFFIX	= .tar.bz2
 INNER_MAKE_PACKAGE 	= $(CREATE_FINAL_TAR) - $(MOZ_PKG_DIR) | bzip2 -vf > $(PACKAGE)
 INNER_UNMAKE_PACKAGE	= bunzip2 -c $(UNPACKAGE) | $(UNPACK_TAR)
 MAKE_SDK = $(CREATE_FINAL_TAR) - $(MOZ_APP_NAME)-sdk | bzip2 -vf > $(SDK)
 endif
 ifeq ($(MOZ_PKG_FORMAT),ZIP)
+ifdef MOZ_EXTERNAL_SIGNING_FORMAT
+# We can't use signcode on zip files
+MOZ_EXTERNAL_SIGNING_FORMAT := $(filter-out signcode,$(MOZ_EXTERNAL_SIGNING_FORMAT))
+endif
 PKG_SUFFIX	= .zip
 INNER_MAKE_PACKAGE	= $(ZIP) -r9D $(PACKAGE) $(MOZ_PKG_DIR)
 INNER_UNMAKE_PACKAGE	= $(UNZIP) $(UNPACKAGE)
 MAKE_SDK = $(ZIP) -r9D $(SDK) $(MOZ_APP_NAME)-sdk
 endif
 ifeq ($(MOZ_PKG_FORMAT),SFX7Z)
 PKG_SUFFIX	= .exe
 INNER_MAKE_PACKAGE	= rm -f app.7z && \
@@ -501,62 +505,86 @@ UNPACK_OMNIJAR	= \
   $(OPTIMIZE_JARS_CMD) --deoptimize $(JARLOG_DIR_AB_CD) ./ ./ && \
   $(UNZIP) -o $(OMNIJAR_NAME) && \
   rm -f components/binary.manifest && \
   for m in components/*.manifest; do \
     sed -e 's/^\#binary-component/binary-component/' $$m > tmp.manifest && \
     mv tmp.manifest $$m; \
   done
 
-MAKE_PACKAGE	= (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(PACK_OMNIJAR)) && \
-	              (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(CREATE_PRECOMPLETE_CMD)) && $(INNER_MAKE_PACKAGE)
+PREPARE_PACKAGE	= (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(PACK_OMNIJAR)) && \
+	              (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(CREATE_PRECOMPLETE_CMD))
 UNMAKE_PACKAGE	= $(INNER_UNMAKE_PACKAGE) && (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(UNPACK_OMNIJAR))
 else
-MAKE_PACKAGE	= (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(CREATE_PRECOMPLETE_CMD)) && $(INNER_MAKE_PACKAGE)
+PREPARE_PACKAGE	= (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(CREATE_PRECOMPLETE_CMD))
 UNMAKE_PACKAGE	= $(INNER_UNMAKE_PACKAGE)
 endif
 
+ifdef MOZ_INTERNAL_SIGNING_FORMAT
+MOZ_SIGN_PREPARED_PACKAGE_CMD=$(MOZ_SIGN_CMD) $(foreach f,$(MOZ_INTERNAL_SIGNING_FORMAT),-f $(f)) $(foreach i,$(SIGN_INCLUDES),-i $(i)) $(foreach x,$(SIGN_EXCLUDES),-x $(x)) --nsscmd "$(SIGN_CMD)"
+endif
+
+# For final GPG / authenticode signing / dmg signing if required
+ifdef MOZ_EXTERNAL_SIGNING_FORMAT
+MOZ_SIGN_PACKAGE_CMD=$(MOZ_SIGN_CMD) $(foreach f,$(MOZ_EXTERNAL_SIGNING_FORMAT),-f $(f))
+ifeq (gpg,$(findstring gpg,$(MOZ_EXTERNAL_SIGNING_FORMAT)))
+UPLOAD_EXTRA_FILES += $(PACKAGE).asc
+endif
+endif
+
+ifdef MOZ_SIGN_PREPARED_PACKAGE_CMD
+MAKE_PACKAGE    = $(PREPARE_PACKAGE) && $(MOZ_SIGN_PREPARED_PACKAGE_CMD) \
+		  $(MOZ_PKG_DIR) && $(INNER_MAKE_PACKAGE)
+else
+MAKE_PACKAGE    = $(PREPARE_PACKAGE) && $(INNER_MAKE_PACKAGE)
+endif
+
+ifdef MOZ_SIGN_PACKAGE_CMD
+MAKE_PACKAGE    += && $(MOZ_SIGN_PACKAGE_CMD) "$(PACKAGE)"
+endif
+
 # dummy macro if we don't have PSM built
 SIGN_NSS		=
 ifdef MOZ_CAN_RUN_PROGRAMS
 ifdef MOZ_PSM
-SIGN_NSS		= @echo signing nss libraries;
+SIGN_NSS		= echo signing nss libraries;
 
 NSS_DLL_SUFFIX	= $(DLL_SUFFIX)
 ifdef UNIVERSAL_BINARY
 NATIVE_ARCH	= $(shell uname -p | sed -e s/powerpc/ppc/)
 NATIVE_DIST	= $(DIST:$(DEPTH)/%=$(DEPTH)/../$(NATIVE_ARCH)/%)
 SIGN_CMD	= $(NATIVE_DIST)/bin/run-mozilla.sh $(NATIVE_DIST)/bin/shlibsign -v -i
 else
 ifeq ($(OS_ARCH),OS2)
 # uppercase extension to get the correct output file from shlibsign
 NSS_DLL_SUFFIX	= .DLL
 SIGN_CMD	= $(MOZILLA_DIR)/toolkit/mozapps/installer/os2/sign.cmd $(DIST)
 else
-SIGN_CMD	= $(RUN_TEST_PROGRAM) $(DIST)/bin/shlibsign$(BIN_SUFFIX) -v -i
+SIGN_CMD	= $(RUN_TEST_PROGRAM) $(_ABS_DIST)/bin/shlibsign$(BIN_SUFFIX) -v -i
 endif
 endif
 
 SOFTOKN		= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)softokn3$(NSS_DLL_SUFFIX)
 NSSDBM		= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)nssdbm3$(NSS_DLL_SUFFIX)
 FREEBL		= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)freebl3$(NSS_DLL_SUFFIX)
 FREEBL_32FPU	= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)freebl_32fpu_3$(DLL_SUFFIX)
 FREEBL_32INT	= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)freebl_32int_3$(DLL_SUFFIX)
 FREEBL_32INT64	= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)freebl_32int64_3$(DLL_SUFFIX)
 FREEBL_64FPU	= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)freebl_64fpu_3$(DLL_SUFFIX)
 FREEBL_64INT	= $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(DLL_PREFIX)freebl_64int_3$(DLL_SUFFIX)
 
-SIGN_NSS	+= $(SIGN_CMD) $(SOFTOKN); \
-	$(SIGN_CMD) $(NSSDBM); \
-	if test -f $(FREEBL); then $(SIGN_CMD) $(FREEBL); fi; \
-	if test -f $(FREEBL_32FPU); then $(SIGN_CMD) $(FREEBL_32FPU); fi; \
-	if test -f $(FREEBL_32INT); then $(SIGN_CMD) $(FREEBL_32INT); fi; \
-	if test -f $(FREEBL_32INT64); then $(SIGN_CMD) $(FREEBL_32INT64); fi; \
-	if test -f $(FREEBL_64FPU); then $(SIGN_CMD) $(FREEBL_64FPU); fi; \
-	if test -f $(FREEBL_64INT); then $(SIGN_CMD) $(FREEBL_64INT); fi;
+SIGN_NSS	+= \
+  $(SIGN_CMD) $(SOFTOKN) && \
+  $(SIGN_CMD) $(NSSDBM) && \
+  if test -f $(FREEBL); then $(SIGN_CMD) $(FREEBL); fi && \
+  if test -f $(FREEBL_32FPU); then $(SIGN_CMD) $(FREEBL_32FPU); fi && \
+  if test -f $(FREEBL_32INT); then $(SIGN_CMD) $(FREEBL_32INT); fi && \
+  if test -f $(FREEBL_32INT64); then $(SIGN_CMD) $(FREEBL_32INT64); fi && \
+  if test -f $(FREEBL_64FPU); then $(SIGN_CMD) $(FREEBL_64FPU); fi && \
+  if test -f $(FREEBL_64INT); then $(SIGN_CMD) $(FREEBL_64INT); fi;
 
 endif # MOZ_PSM
 endif # !CROSS_COMPILE
 
 NO_PKG_FILES += \
 	core \
 	bsdecho \
 	js \
@@ -658,16 +686,19 @@ ifdef MOZ_OPTIONAL_PKG_LIST
 	  $(foreach pkg,$(MOZ_OPTIONAL_PKG_LIST),$(PKG_ARG)) )
 	if test -d $(DEPTH)/installer-stage/optional/extensions ; then \
 		cd $(DEPTH)/installer-stage/optional/extensions; find -maxdepth 1 -mindepth 1 -exec rm -r ../../core/extensions/{} \; ; \
 	fi
 	if test -d $(DEPTH)/installer-stage/optional/distribution/extensions/ ; then \
 		cd $(DEPTH)/installer-stage/optional/distribution/extensions/; find -maxdepth 1 -mindepth 1 -exec rm -r ../../../core/distribution/extensions/{} \; ; \
 	fi
 endif
+ifdef MOZ_SIGN_PREPARED_PACKAGE_CMD
+	$(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(DEPTH)/installer-stage
+endif
 
 elfhack:
 ifdef USE_ELF_HACK
 	@echo ===
 	@echo === If you get failures below, please file a bug describing the error
 	@echo === and your environment \(compiler and linker versions\), and use
 	@echo === --disable-elf-hack until this is fixed.
 	@echo ===
@@ -747,17 +778,17 @@ ifndef PKG_SKIP_STRIP
 				! -name "*.tbl" \
 				! -name "*.src" \
 				! -name "*.reg" \
 				$(PLATFORM_EXCLUDE_LIST) \
 				-exec $(STRIP) $(STRIP_FLAGS) {} >/dev/null 2>&1 \;
   endif
 endif # PKG_SKIP_STRIP
 # We always sign nss because we don't do it from security/manager anymore
-	$(SIGN_NSS)
+	@$(SIGN_NSS)
 	@echo "Removing unpackaged files..."
 ifdef NO_PKG_FILES
 	cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH); rm -rf $(NO_PKG_FILES)
 endif
 ifdef MOZ_PKG_REMOVALS
 	$(SYSINSTALL) $(IFLAGS1) $(MOZ_PKG_REMOVALS_GEN) $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)
 endif # MOZ_PKG_REMOVALS
 ifdef MOZ_POST_STAGING_CMD
@@ -863,46 +894,62 @@ QUOTED_WILDCARD = $(if $(wildcard $(subs
 ESCAPE_SPACE = $(subst $(space),\$(space),$(1))
 
 # This variable defines which OpenSSL algorithm to use to 
 # generate checksums for files that we upload
 CHECKSUM_ALGORITHM = 'sha512'
 
 # This variable defines where the checksum file will be located
 CHECKSUM_FILE = "$(DIST)/$(PKG_PATH)/$(PKG_BASENAME).checksums"
+CHECKSUM_FILES = $(CHECKSUM_FILE)
 
 UPLOAD_FILES= \
   $(call QUOTED_WILDCARD,$(DIST)/$(PACKAGE)) \
   $(call QUOTED_WILDCARD,$(INSTALLER_PACKAGE)) \
   $(call QUOTED_WILDCARD,$(DIST)/$(COMPLETE_MAR)) \
   $(call QUOTED_WILDCARD,$(DIST)/$(LANGPACK)) \
   $(call QUOTED_WILDCARD,$(wildcard $(DIST)/$(PARTIAL_MAR))) \
   $(call QUOTED_WILDCARD,$(DIST)/$(PKG_PATH)$(TEST_PACKAGE)) \
   $(call QUOTED_WILDCARD,$(DIST)/$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip) \
   $(call QUOTED_WILDCARD,$(DIST)/$(SDK)) \
   $(call QUOTED_WILDCARD,$(MOZ_SOURCESTAMP_FILE)) \
   $(call QUOTED_WILDCARD,$(PKG_JSSHELL)) \
   $(if $(UPLOAD_EXTRA_FILES), $(foreach f, $(UPLOAD_EXTRA_FILES), $(wildcard $(DIST)/$(f))))
 
+SIGN_CHECKSUM_CMD=
+ifdef MOZ_SIGN_CMD
+ifeq (gpg,$(filter gpg,$(MOZ_EXTERNAL_SIGNING_FORMAT)))
+# If we're signing with gpg, we'll have a bunch of extra detached signatures to
+# upload. We also want to sign our checksums file
+SIGN_CHECKSUM_CMD=$(MOZ_SIGN_CMD) -f gpg $(CHECKSUM_FILE)
+
+CHECKSUM_FILES += $(CHECKSUM_FILE).asc
+UPLOAD_FILES += $(call QUOTED_WILDCARD,$(DIST)/$(COMPLETE_MAR).asc)
+UPLOAD_FILES += $(call QUOTED_WILDCARD,$(wildcard $(DIST)/$(PARTIAL_MAR).asc))
+UPLOAD_FILES += $(call QUOTED_WILDCARD,$(INSTALLER_PACKAGE).asc)
+endif
+endif
+
 checksum:
 	mkdir -p `dirname $(CHECKSUM_FILE)`
 	@$(PYTHON) $(MOZILLA_DIR)/build/checksums.py \
 		-o $(CHECKSUM_FILE) \
 		-d $(CHECKSUM_ALGORITHM) \
 		-s $(call QUOTED_WILDCARD,$(DIST)) \
 		$(UPLOAD_FILES)
 	@echo "CHECKSUM FILE START"
 	@cat $(CHECKSUM_FILE)
 	@echo "CHECKSUM FILE END"
+	$(SIGN_CHECKSUM_CMD)
 
 
 upload: checksum
 	$(PYTHON) $(MOZILLA_DIR)/build/upload.py --base-path $(DIST) \
 		$(UPLOAD_FILES) \
-		$(CHECKSUM_FILE)
+		$(CHECKSUM_FILES)
 
 ifeq (WINNT,$(OS_TARGET))
 CODESIGHS_PACKAGE = $(INSTALLER_PACKAGE)
 else
 CODESIGHS_PACKAGE = $(DIST)/$(PACKAGE)
 endif
 
 codesighs:
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/signing.mk
@@ -0,0 +1,60 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# Contributor(s):
+#   Chris AtLee <catlee@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# We shouldn't sign the first pass of a PGO build
+ifndef MOZ_PROFILE_GENERATE
+
+# Signing support
+ifdef MOZ_SIGN_CMD
+ifeq (WINNT,$(OS_ARCH))
+MOZ_INTERNAL_SIGNING_FORMAT := signcode
+MOZ_EXTERNAL_SIGNING_FORMAT := signcode gpg
+SIGN_INCLUDES := \
+  '*.dll' \
+  '*.exe' \
+  $(NULL)
+
+SIGN_EXCLUDES := \
+  'D3DCompiler*.dll' \
+  'd3dx9*.dll' \
+  'msvc*.dll' \
+  $(NULL)
+endif # Windows
+
+ifeq (Darwin, $(OS_ARCH))
+MOZ_EXTERNAL_SIGNING_FORMAT := gpg
+endif # Darwin
+
+ifeq (linux-gnu,$(TARGET_OS))
+MOZ_EXTERNAL_SIGNING_FORMAT := gpg
+endif # Linux
+endif # MOZ_SIGN_CMD
+
+endif # MOZ_PROFILE_GENERATE
--- a/toolkit/mozapps/installer/windows/nsis/makensis.mk
+++ b/toolkit/mozapps/installer/windows/nsis/makensis.mk
@@ -36,16 +36,18 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 ifndef CONFIG_DIR
 $(error CONFIG_DIR must be set before including makensis.mk)
 endif
 
+include $(topsrcdir)/toolkit/mozapps/installer/signing.mk
+
 ABS_CONFIG_DIR := $(shell pwd)/$(CONFIG_DIR)
 
 SFX_MODULE ?= $(error SFX_MODULE is not defined)
 
 TOOLKIT_NSIS_FILES = \
 	common.nsh \
 	locales.nsi \
 	overrides.nsh \
@@ -66,27 +68,33 @@ CUSTOM_NSIS_PLUGINS = \
 $(CONFIG_DIR)/setup.exe::
 	$(INSTALL) $(addprefix $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
 	$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/Plugins/,$(CUSTOM_NSIS_PLUGINS)) $(CONFIG_DIR)
 	cd $(CONFIG_DIR) && $(MAKENSISU) installer.nsi
 # Support for building the uninstaller when repackaging locales
 ifeq ($(CONFIG_DIR),l10ngen)
 	cd $(CONFIG_DIR) && $(MAKENSISU) uninstaller.nsi
 endif
+ifdef MOZ_EXTERNAL_SIGNING_FORMAT
+	$(MOZ_SIGN_CMD) $(foreach f,$(MOZ_EXTERNAL_SIGNING_FORMAT),-f $(f)) "$@"
+endif
 
 $(CONFIG_DIR)/7zSD.sfx:
 	$(CYGWIN_WRAPPER) upx --best -o $(CONFIG_DIR)/7zSD.sfx $(SFX_MODULE)
 
 installer::
 	$(INSTALL) $(CONFIG_DIR)/setup.exe $(DEPTH)/installer-stage
 	cd $(DEPTH)/installer-stage && $(CYGWIN_WRAPPER) 7z a -r -t7z $(ABS_CONFIG_DIR)/app.7z -mx -m0=BCJ2 -m1=LZMA:d24 -m2=LZMA:d19 -m3=LZMA:d19  -mb0:1 -mb0s1:2 -mb0s2:3
 	$(MAKE) $(CONFIG_DIR)/7zSD.sfx
 	$(NSINSTALL) -D $(DIST)/$(PKG_INST_PATH)
 	cat $(CONFIG_DIR)/7zSD.sfx $(CONFIG_DIR)/app.tag $(CONFIG_DIR)/app.7z > "$(DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe"
 	chmod 0755 "$(DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe"
+ifdef MOZ_EXTERNAL_SIGNING_FORMAT
+	$(MOZ_SIGN_CMD) $(foreach f,$(MOZ_EXTERNAL_SIGNING_FORMAT),-f $(f)) "$(DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe"
+endif
 
 # For building the uninstaller during the application build so it can be
 # included for mar file generation.
 uninstaller::
 	$(INSTALL) $(addprefix $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
 	$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/Plugins/,$(CUSTOM_NSIS_PLUGINS)) $(CONFIG_DIR)
 	cd $(CONFIG_DIR) && $(MAKENSISU) uninstaller.nsi
 	$(NSINSTALL) -D $(DIST)/bin/uninstall
--- a/tools/update-packaging/Makefile.in
+++ b/tools/update-packaging/Makefile.in
@@ -73,31 +73,44 @@ full-update:: complete-patch
 ifeq ($(OS_TARGET), WINNT)
 MOZ_PKG_FORMAT	:= SFX7Z
 UNPACKAGE	= "$(subst $(DIST),$(_ABS_DIST),$(INSTALLER_PACKAGE))"
 ifdef AB_CD
 UNPACKAGE	= "$(PACKAGE_BASE_DIR)/$(PACKAGE)"
 endif
 endif
 
+include $(topsrcdir)/config/rules.mk
+include $(topsrcdir)/toolkit/mozapps/installer/signing.mk
+include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
+
+ifdef MOZ_EXTERNAL_SIGNING_FORMAT
+# We can't use signcode on mar files
+MOZ_EXTERNAL_SIGNING_FORMAT := $(filter-out signcode,$(MOZ_EXTERNAL_SIGNING_FORMAT))
+MOZ_EXTERNAL_SIGNING_FORMAT := mar $(MOZ_EXTERNAL_SIGNING_FORMAT)
+endif
+
 complete-patch::
 ifeq ($(OS_TARGET), WINNT)
 	test -f $(UNPACKAGE)
 	$(RM) -rf "$(PACKAGE_DIR)"
 	cd $(PACKAGE_BASE_DIR) && $(INNER_UNMAKE_PACKAGE)
 endif
 	mkdir -p $(STAGE_DIR)
 	MAR=$(MAR_BIN) \
 	  $(srcdir)/make_full_update.sh \
 	  "$(STAGE_DIR)/$(PKG_UPDATE_BASENAME).complete.mar" \
 	  "$(PACKAGE_DIR)"
+ifdef MOZ_SIGN_PACKAGE_CMD
+	$(MOZ_SIGN_PACKAGE_CMD) "$(STAGE_DIR)/$(PKG_UPDATE_BASENAME).complete.mar"
+endif
 
 partial-patch::
 	mkdir -p $(STAGE_DIR)
 	MAR=$(MAR_BIN) \
 	MBSDIFF=$(MBSDIFF_BIN) \
 	  $(srcdir)/make_incremental_update.sh \
 	  "$(STAGE_DIR)/$(PKG_UPDATE_BASENAME).partial.$(SRC_BUILD_ID)-$(DST_BUILD_ID).mar" \
 	  "$(SRC_BUILD)" \
 	  "$(DST_BUILD)"
-
-include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
+ifdef MOZ_SIGN_PACKAGE_CMD
+	$(MOZ_SIGN_PACKAGE_CMD) "$(STAGE_DIR)/$(PKG_UPDATE_BASENAME).partial.$(SRC_BUILD_ID)-$(DST_BUILD_ID).mar"
+endif