make-rules/ips.mk
branchs11-update
changeset 3996 20c0f21bbe1e
parent 3787 e0eb0826110c
child 4072 db0cec748ec0
--- a/make-rules/ips.mk	Thu Mar 19 14:35:58 2015 -0700
+++ b/make-rules/ips.mk	Thu Mar 19 20:44:31 2015 -0700
@@ -18,14 +18,16 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+
+#
+# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
 #
 
 #
 # Rules and Macros for generating an IPS package manifest and publishing an
 # IPS package to a pkg depot.
 #
-# To use these rules, include ../make-rules/ips.mk in your Makefile
+# To use these rules, include $(WS_MAKE_RULES)/ips.mk in your Makefile
 # and define an "install" target appropriate to building your component.
 # Ex:
 #
@@ -46,6 +48,8 @@
 endif
 PKGMANGLE =	$(WS_TOOLS)/userland-mangler
 
+WS_TRANSFORMS =	$(WS_TOP)/transforms
+
 # Package headers should all pretty much follow the same format
 METADATA_TEMPLATE =		$(WS_TOP)/transforms/manifest-metadata-template
 COPYRIGHT_TEMPLATE =		$(WS_TOP)/transforms/copyright-template
@@ -86,6 +90,7 @@
 PKG_MACROS +=		BUILD_VERSION=$(BUILD_VERSION)
 PKG_MACROS +=		SOLARIS_VERSION=$(SOLARIS_VERSION)
 PKG_MACROS +=		OS_VERSION=$(OS_VERSION)
+PKG_MACROS +=		PKG_SOLARIS_VERSION=$(PKG_SOLARIS_VERSION)
 PKG_MACROS +=		HUMAN_VERSION=$(HUMAN_VERSION)
 PKG_MACROS +=		IPS_COMPONENT_VERSION=$(IPS_COMPONENT_VERSION)
 PKG_MACROS +=		COMPONENT_VERSION=$(COMPONENT_VERSION)
@@ -218,7 +223,7 @@
 # appropriate conditional dependencies into a python library's
 # runtime-version-generic package to pull in the version-specific bits when the
 # corresponding version of python is on the system.
-$(BUILD_DIR)/mkgeneric-python: $(WS_TOP)/make-rules/shared-macros.mk
+$(BUILD_DIR)/mkgeneric-python: $(WS_MAKE_RULES)/shared-macros.mk
 	$(RM) [email protected]
 	$(foreach ver,$(shell echo $(PYTHON_VERSIONS) | tr -d .), \
 		$(call mkgeneric,runtime/python,$(ver)))
@@ -250,7 +255,7 @@
 # appropriate conditional dependencies into a perl library's
 # runtime-version-generic package to pull in the version-specific bits when the
 # corresponding version of perl is on the system.
-$(BUILD_DIR)/mkgeneric-perl: $(WS_TOP)/make-rules/shared-macros.mk
+$(BUILD_DIR)/mkgeneric-perl: $(WS_MAKE_RULES)/shared-macros.mk
 	$(RM) [email protected]
 	$(foreach ver,$(shell echo $(PERL_VERSIONS) | tr -d .), \
 		$(call mkgeneric,runtime/perl,$(ver)))
@@ -259,6 +264,7 @@
 # See the block comment above about why "###PYV###" is used here even
 # though this is for Perl rather than Python.
 $(MANIFEST_BASE)-%.p5m: %-PERLVER.p5m $(BUILD_DIR)/mkgeneric-perl
+	$(PKGFMT) $(PKGFMT_CHECK_ARGS) $(CANONICAL_MANIFESTS)
 	$(PKGMOGRIFY) -D PLV=###PYV### $(BUILD_DIR)/mkgeneric-perl \
 		$(WS_TOP)/transforms/mkgeneric $< > [email protected]
 	if [ -f $*-GENFRAG.p5m ]; then cat $*-GENFRAG.p5m >> [email protected]; fi
@@ -287,7 +293,7 @@
 # appropriate conditional dependencies into a ruby library's
 # runtime-version-generic package to pull in the version-specific bits when the
 # corresponding version of ruby is on the system.
-$(BUILD_DIR)/mkgeneric-ruby: $(WS_TOP)/make-rules/shared-macros.mk
+$(BUILD_DIR)/mkgeneric-ruby: $(WS_MAKE_RULES)/shared-macros.mk
 	$(RM) [email protected]
 	$(foreach ver,$(RUBY_VERSIONS),\
 		$(call mkgeneric,runtime/ruby,$(shell echo $(ver) | \
@@ -329,41 +335,39 @@
 	$(ENV) $(COMPONENT_PUBLISH_ENV) $(PKGDEPEND) generate \
 	    $(PKGDEPEND_GENERATE_OPTIONS) $< >[email protected]
 
-# These files should contain a list of packages that the component is known to
-# depend on.  Using resolve.deps is not required, but significantly speeds up
-# the "pkg resolve" step.
-EXTDEPFILES ?= $(wildcard $(sort $(addsuffix ../resolve.deps, $(dir $(DEPENDED)))))
-
-# If the package contains no automatically discoverable dependencies, then
-# we can speed up resolution by providing a dummy resolve.deps to skip loading
-# all the possible packages for resolution.  Unfortunately, pkgdepend does not
-# accept a completely empty resolve.deps, so we pass the userland-incorporation
-# as a quick, content-free placeholder.
-NULLDEPFILE = $(BUILD_DIR)/null-resolve.deps
+# pkgdepend resolve builds a map of all installed packages by default.  This
+# makes dependency resolution particularly slow.  We can dramatically improve
+# performance here by creating a file with a list of packages that we know
+# are needed, dramatically reducing the overhead involved in creating and
+# searching this map.
+#
+# Generate a resolve.deps file from the dependencies in the Makefile and
+# fragments that it uses.
+RESOLVE_DEPS=$(BUILD_DIR)/resolve.deps
 
-# This is a target that should only be run by hand, and not something that
-# .resolved-$(MACH) should depend on.
-sample-resolve.deps:
-	@echo "<transform depend type=(require|require-any) -> print %(fmri)>" > rd-trans
-	@for i in build/*.depend; do \
-		$(PKGMOGRIFY) -O /dev/null $$i rd-trans | tr " " "\n" | sort -u > m1; \
-		$(PKGMOGRIFY) -O /dev/null $$i.res rd-trans | tr " " "\n" | sort -u > m2; \
-		comm -13 m1 m2; \
-	done | sed -e 's/@[^ ]*//g' -e 's,pkg:/,,g' | sort -u > resolve.deps
-	@$(RM) rd-trans m1 m2
-	@if [[ ! -s resolve.deps ]]; then \
-		echo "No computed dependencies found; removing empty resolve.deps."; \
-		$(RM) resolve.deps; \
-	fi
+$(RESOLVE_DEPS):	$(MAKEFILE_PREREQ) $(BUILD_DIR)
+	@for pkg in $(REQUIRED_PACKAGES:%=/%) ; do \
+	    echo $${pkg} ; \
+	done | sort -u >[email protected]
 
 # resolve the dependencies all at once
-$(BUILD_DIR)/.resolved-$(MACH):	$(DEPENDED)
-	if [[ "$(EXTDEPFILES)" == "$(NULLDEPFILE)" ]] ; then \
-	  echo 'consolidation/userland/userland-incorporation' > $(NULLDEPFILE) ; \
-	fi
-	$(PKGDEPEND) resolve $(EXTDEPFILES:%=-e %) -m $(DEPENDED)
+$(BUILD_DIR)/.resolved-$(MACH):	$(DEPENDED) $(RESOLVE_DEPS)
+	$(PKGDEPEND) resolve $(RESOLVE_DEPS:%=-e %) -m $(DEPENDED)
 	$(TOUCH) [email protected]
 
+#
+# Generate a set of REQUIRED_PACKAGES based on what is needed to for pkgdepend
+# to resolve properly.  Automatically append this to your Makefile for the truly
+# lazy among us.  This is only a piece of the REQUIRED_PACKAGES puzzle.
+# You must still include packages for tools you build and test with.
+#
+REQUIRED_PACKAGES::	$(RESOLVED)
+	$(GMAKE) RESOLVE_DEPS= $(BUILD_DIR)/.resolved-$(MACH)
+	@echo "# Auto-generated contents below.  Please manually verify and remove this comment" >>Makefile
+	@$(PKGMOGRIFY) $(WS_TRANSFORMS)/[email protected] $(RESOLVED) | \
+		$(GSED) -e '/^[\t ]*$$/d' -e '/^#/d' | sort -u >>Makefile
+	@echo "*** Please edit your Makefile and verify the new content at the end ***"
+
 # lint the manifests all at once
 $(BUILD_DIR)/.linted-$(MACH):	$(BUILD_DIR)/.resolved-$(MACH)
 	@echo "VALIDATING MANIFEST CONTENT: $(RESOLVED)"
@@ -388,6 +392,7 @@
 PKGSEND_PUBLISH_OPTIONS += --no-catalog
 PKGSEND_PUBLISH_OPTIONS += $(PKG_PROTO_DIRS:%=-d %)
 PKGSEND_PUBLISH_OPTIONS += -T \*.py
+
 $(MANIFEST_BASE)-%.published:	$(MANIFEST_BASE)-%.depend.res $(BUILD_DIR)/.linted-$(MACH)
 	$(PKGSEND) $(PKGSEND_PUBLISH_OPTIONS) $<
 	$(PKGFMT) <$< >[email protected]
@@ -420,7 +425,7 @@
 
 $(RESOLVED):	install
 
-canonical-manifests:	$(CANONICAL_MANIFESTS) Makefile $(PATCHES)
+canonical-manifests:	$(CANONICAL_MANIFESTS) $(MAKEFILE_PREREQ) $(PATCHES)
 ifeq	($(strip $(CANONICAL_MANIFESTS)),)
 	# If there were no canonical manifests in the workspace, nothing will
 	# be published and we should fail.  A sample manifest can be generated
@@ -433,7 +438,7 @@
 
 # This converts required paths to containing package names for be able to
 # properly setup the build environment for a component.
-required-pkgs.mk:	Makefile
+required-pkgs.mk:	$(MAKEFILE_PREREQ)
 	@echo "generating [email protected] from Makefile REQUIRED_* data"
 	@pkg search -H -l '<$(DEPENDS:%=% OR) /bin/true>' \
 		| sed -e 's/pkg:\/\(.*\)@.*/REQUIRED_PKGS += \1/g' >[email protected]