Bring mtr from sustaining oi-build
[unleashed-userland.git] / make-rules / ips.mk
blob7ff30aed59b6556d214a65fa7faad9d691a3166c
2 # CDDL HEADER START
4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
19 # CDDL HEADER END
21 # Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
25 # Rules and Macros for generating an IPS package manifest and publishing an
26 # IPS package to a pkg depot.
28 # To use these rules, include ../make-rules/ips.mk in your Makefile
29 # and define an "install" target appropriate to building your component.
30 # Ex:
32 # install: $(BUILD_DIR)/build/$(MACH32)/.installed \
33 # $(BUILD_DIR)/build/$(MACH64)/.installed
35 # This set of rules makes the "publish" target the default target for make(1)
38 PKGDEPEND = /usr/bin/pkgdepend
39 PKGFMT = /usr/bin/pkgfmt
40 PKGMOGRIFY = /usr/bin/pkgmogrify
41 PKGSEND = /usr/bin/pkgsend
42 ifeq ($(strip $(PKGLINT_COMPONENT)),)
43 PKGLINT = /usr/bin/pkglint
44 else
45 PKGLINT = ${WS_TOOLS}/pkglint
46 endif
47 PKGMANGLE = $(WS_TOOLS)/userland-mangler
49 # Package headers should all pretty much follow the same format
50 METADATA_TEMPLATE = $(WS_TOP)/transforms/manifest-metadata-template
51 COPYRIGHT_TEMPLATE = $(WS_TOP)/transforms/copyright-template
53 # order is important
54 GENERATE_TRANSFORMS += $(WS_TOP)/transforms/generate-cleanup
56 PKGMOGRIFY_TRANSFORMS += $(WS_TOP)/transforms/libtool-drop
58 COMPARISON_TRANSFORMS += $(WS_TOP)/transforms/comparison-cleanup
59 COMPARISON_TRANSFORMS += $(PKGMOGRIFY_TRANSFORMS)
61 LICENSE_TRANSFORMS = $(WS_TOP)/transforms/license-changes
63 # order is important
64 PUBLISH_TRANSFORMS += $(LICENSE_TRANSFORMS)
65 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/variant-cleanup
66 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/autopyc
67 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/defaults
68 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/actuators
69 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/devel
70 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/docs
71 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/locale
72 PUBLISH_TRANSFORMS += $(PKGMOGRIFY_TRANSFORMS)
73 PUBLISH_TRANSFORMS += $(WS_TOP)/transforms/publish-cleanup
75 PKG_MACROS += MACH=$(MACH)
76 PKG_MACROS += MACH32=$(MACH32)
77 PKG_MACROS += MACH64=$(MACH64)
78 PKG_MACROS += PUBLISHER=$(PUBLISHER)
79 PKG_MACROS += PUBLISHER_LOCALIZABLE=$(PUBLISHER_LOCALIZABLE)
80 PKG_MACROS += CONSOLIDATION=$(CONSOLIDATION)
81 PKG_MACROS += BUILD_VERSION=$(BUILD_VERSION)
82 PKG_MACROS += SOLARIS_VERSION=$(SOLARIS_VERSION)
83 PKG_MACROS += OS_VERSION=$(OS_VERSION)
84 PKG_MACROS += PKG_SOLARIS_VERSION=$(PKG_SOLARIS_VERSION)
85 PKG_MACROS += HUMAN_VERSION=$(HUMAN_VERSION)
86 PKG_MACROS += IPS_COMPONENT_VERSION=$(IPS_COMPONENT_VERSION)
87 PKG_MACROS += COMPONENT_VERSION=$(COMPONENT_VERSION)
88 PKG_MACROS += COMPONENT_PROJECT_URL=$(COMPONENT_PROJECT_URL)
89 PKG_MACROS += COMPONENT_ARCHIVE_URL=$(COMPONENT_ARCHIVE_URL)
90 PKG_MACROS += COMPONENT_HG_URL=$(COMPONENT_HG_URL)
91 PKG_MACROS += COMPONENT_HG_REV=$(COMPONENT_HG_REV)
92 PKG_MACROS += COMPONENT_NAME=$(COMPONENT_NAME)
93 PKG_MACROS += TPNO=$(TPNO)
95 PKG_OPTIONS += $(PKG_MACROS:%=-D %) -D COMPONENT_SUMMARY="$(COMPONENT_SUMMARY)"
97 MANGLED_DIR = $(PROTO_DIR)/mangled
99 PKG_PROTO_DIRS += $(MANGLED_DIR) $(PROTO_DIR) $(@D) $(COMPONENT_DIR) $(COMPONENT_SRC)
101 MANIFEST_BASE = $(BUILD_DIR)/manifest-$(MACH)
103 CANONICAL_MANIFESTS = $(wildcard *.p5m)
105 # Look for manifests which need to be duplicated for each version of python.
106 ifeq ($(findstring -PYVER,$(CANONICAL_MANIFESTS)),-PYVER)
107 UNVERSIONED_MANIFESTS = $(filter-out %-GENFRAG.p5m,$(filter-out %-PYVER.p5m,$(CANONICAL_MANIFESTS)))
108 PY_MANIFESTS = $(filter %-PYVER.p5m,$(CANONICAL_MANIFESTS))
109 PYV_MANIFESTS = $(foreach v,$(shell echo $(PYTHON_VERSIONS) | tr -d .),$(shell echo $(PY_MANIFESTS) | sed -e 's/-PYVER.p5m/-$(v).p5m/g'))
110 PYNV_MANIFESTS = $(shell echo $(PY_MANIFESTS) | sed -e 's/-PYVER//')
111 else
112 UNVERSIONED_MANIFESTS = $(CANONICAL_MANIFESTS)
113 endif
115 # Look for manifests which need to be duplicated for each version of perl.
116 ifeq ($(findstring -PERLVER,$(UNVERSIONED_MANIFESTS)),-PERLVER)
117 NOPERL_MANIFESTS = $(filter-out %-GENFRAG.p5m,$(filter-out %-PERLVER.p5m,$(UNVERSIONED_MANIFESTS)))
118 PERL_MANIFESTS = $(filter %-PERLVER.p5m,$(UNVERSIONED_MANIFESTS))
119 PERLV_MANIFESTS = $(foreach v,$(shell echo $(PERL_VERSIONS) | tr -d .),$(shell echo $(PERL_MANIFESTS) | sed -e 's/-PERLVER.p5m/-$(v).p5m/g'))
120 PERLNV_MANIFESTS = $(shell echo $(PERL_MANIFESTS) | sed -e 's/-PERLVER//')
121 else
122 NOPERL_MANIFESTS = $(UNVERSIONED_MANIFESTS)
123 endif
125 VERSIONED_MANIFESTS = \
126 $(PYV_MANIFESTS) $(PYNV_MANIFESTS) \
127 $(PERLV_MANIFESTS) $(PERLNV_MANIFESTS) \
128 $(NOPERL_MANIFESTS)
130 GENERATED = $(MANIFEST_BASE)-generated
131 COMBINED = $(MANIFEST_BASE)-combined
132 MANIFESTS = $(VERSIONED_MANIFESTS:%=$(MANIFEST_BASE)-%)
135 DEPENDED=$(VERSIONED_MANIFESTS:%.p5m=$(MANIFEST_BASE)-%.depend)
136 RESOLVED=$(VERSIONED_MANIFESTS:%.p5m=$(MANIFEST_BASE)-%.depend.res)
137 PUBLISHED=$(RESOLVED:%.depend.res=%.published)
139 COPYRIGHT_FILE ?= $(COMPONENT_NAME)-$(COMPONENT_VERSION).copyright
140 IPS_COMPONENT_VERSION ?= $(COMPONENT_VERSION)
142 .DEFAULT: publish
144 .SECONDARY:
146 # allow publishing to be overridden, such as when
147 # a package is for one architecture only.
148 PUBLISH_STAMP ?= $(BUILD_DIR)/.published-$(MACH)
150 publish: build install $(PUBLISH_STAMP)
152 sample-manifest: $(GENERATED).p5m
154 $(GENERATED).p5m: install
155 $(PKGSEND) generate $(PKG_HARDLINKS:%=--target %) $(PROTO_DIR) | \
156 $(PKGMOGRIFY) $(PKG_OPTIONS) /dev/fd/0 $(GENERATE_TRANSFORMS) | \
157 sed -e '/^$$/d' -e '/^#.*$$/d' | $(PKGFMT) | \
158 cat $(METADATA_TEMPLATE) - >$@
160 # copy the canonical manifest(s) to the build tree
161 $(MANIFEST_BASE)-%.generate: %.p5m canonical-manifests
162 cat $(METADATA_TEMPLATE) $< >$@
164 # The text of a transform that will emit a dependency conditional on the
165 # presence of a particular version of a runtime, which will then draw in the
166 # runtime-version-specific version of the package we're operating on. $(1) is
167 # the name of the runtime package, and $(2) is the version suffix.
168 mkgeneric = \
169 echo "<transform set name=pkg.fmri value=(?:pkg:/)?(.+)-\#\#\#@(.*)" \
170 "-> emit depend nodrop=true type=conditional" \
171 "predicate=$(1)-$(2) fmri=%<1>-$(2)@%<2>>" >> $@;
173 # Define and execute a macro that generates a rule to create a manifest for a
174 # python module specific to a particular version of the python runtime.
175 define python-manifest-rule
176 $(MANIFEST_BASE)-%-$(shell echo $(1) | tr -d .).p5m: %-PYVER.p5m
177 $(PKGMOGRIFY) -D PYVER=$(1) -D PYV=$(shell echo $(1) | tr -d .) $$< > $$@
178 endef
179 $(foreach ver,$(PYTHON_VERSIONS),$(eval $(call python-manifest-rule,$(ver))))
181 # A rule to create a helper transform package for python, that will insert the
182 # appropriate conditional dependencies into a python library's
183 # runtime-version-generic package to pull in the version-specific bits when the
184 # corresponding version of python is on the system.
185 $(WS_TOP)/transforms/mkgeneric-python: $(WS_TOP)/make-rules/shared-macros.mk
186 $(RM) $@
187 $(foreach ver,$(shell echo $(PYTHON_VERSIONS) | tr -d .), \
188 $(call mkgeneric,runtime/python,$(ver)))
190 # Build Python version-wrapping manifests from the generic version.
191 $(MANIFEST_BASE)-%.p5m: %-PYVER.p5m $(WS_TOP)/transforms/mkgeneric-python
192 $(PKGMOGRIFY) -D PYV=### $(WS_TOP)/transforms/mkgeneric-python \
193 $(WS_TOP)/transforms/mkgeneric $< > $@
194 if [ -f $*-GENFRAG.p5m ]; then cat $*-GENFRAG.p5m >> $@; fi
196 # Define and execute a macro that generates a rule to create a manifest for a
197 # perl module specific to a particular version of the perl runtime.
198 define perl-manifest-rule
199 $(MANIFEST_BASE)-%-$(shell echo $(1) | tr -d .).p5m: %-PERLVER.p5m
200 $(PKGMOGRIFY) -D PERLVER=$(1) -D PLV=$(shell echo $(1) | tr -d .) \
201 -D PERL_ARCH=$(call PERL_ARCH_FUNC,$(PERL.$(1))) $$< > $$@
202 endef
203 $(foreach ver,$(PERL_VERSIONS),$(eval $(call perl-manifest-rule,$(ver))))
205 # A rule to create a helper transform package for perl, that will insert the
206 # appropriate conditional dependencies into a perl library's
207 # runtime-version-generic package to pull in the version-specific bits when the
208 # corresponding version of perl is on the system.
209 $(WS_TOP)/transforms/mkgeneric-perl: $(WS_TOP)/make-rules/shared-macros.mk
210 $(RM) $@
211 $(foreach ver,$(shell echo $(PERL_VERSIONS) | tr -d .), \
212 $(call mkgeneric,runtime/perl,$(ver)))
214 # Build Perl version-wrapping manifests from the generic version.
215 $(MANIFEST_BASE)-%.p5m: %-PERLVER.p5m $(WS_TOP)/transforms/mkgeneric-perl
216 $(PKGMOGRIFY) -D PLV=### $(WS_TOP)/transforms/mkgeneric-perl \
217 $(WS_TOP)/transforms/mkgeneric $< > $@
218 if [ -f $*-GENFRAG.p5m ]; then cat $*-GENFRAG.p5m >> $@; fi
220 # mogrify non-parameterized manifests
221 $(MANIFEST_BASE)-%.mogrified: %.p5m $(BUILD_DIR)
222 $(PKGMOGRIFY) $(PKG_OPTIONS) $< \
223 $(PUBLISH_TRANSFORMS) | \
224 sed -e '/^$$/d' -e '/^#.*$$/d' | uniq >$@
226 # mogrify parameterized manifests
227 $(MANIFEST_BASE)-%.mogrified: $(MANIFEST_BASE)-%.p5m $(BUILD_DIR)
228 $(PKGMOGRIFY) $(PKG_OPTIONS) $< \
229 $(PUBLISH_TRANSFORMS) | \
230 sed -e '/^$$/d' -e '/^#.*$$/d' | uniq >$@
232 # mangle the file contents
233 $(BUILD_DIR) $(MANGLED_DIR):
234 $(MKDIR) $@
236 PKGMANGLE_OPTIONS = -D $(MANGLED_DIR) $(PKG_PROTO_DIRS:%=-d %)
237 $(MANIFEST_BASE)-%.mangled: $(MANIFEST_BASE)-%.mogrified $(MANGLED_DIR)
238 $(PKGMANGLE) $(PKGMANGLE_OPTIONS) -m $< >$@
240 # generate dependencies
241 PKGDEPEND_GENERATE_OPTIONS = -m $(PKG_PROTO_DIRS:%=-d %)
242 $(MANIFEST_BASE)-%.depend: $(MANIFEST_BASE)-%.mangled
243 $(PKGDEPEND) generate $(PKGDEPEND_GENERATE_OPTIONS) $< >$@
245 # These files should contain a list of packages that the component is known to
246 # depend on. Using resolve.deps is not required, but significantly speeds up
247 # the "pkg resolve" step.
248 # XXX existing pkg5 is too old for that
249 #EXTDEPFILES = $(wildcard $(sort $(addsuffix ../resolve.deps, $(dir $(DEPENDED)))))
251 # This is a target that should only be run by hand, and not something that
252 # .resolved-$(MACH) should depend on.
253 sample-resolve.deps:
254 echo "<transform depend type=(require|require-any) -> print %(fmri)>" > rd-trans
255 for i in build/*.depend; do \
256 $(PKGMOGRIFY) -O /dev/null $$i rd-trans | tr " " "\n" | sort -u > m1; \
257 $(PKGMOGRIFY) -O /dev/null $$i.res rd-trans | tr " " "\n" | sort -u > m2; \
258 comm -13 m1 m2; \
259 done | sed -e 's/@[^ ]*//g' -e 's,pkg:/,,g' | sort -u > resolve.deps
260 $(RM) rd-trans m1 m2
261 if [[ ! -s resolve.deps ]]; then \
262 echo "No computed dependencies found; removing empty resolve.deps."; \
263 $(RM) resolve.deps; \
267 # resolve the dependencies all at once
268 $(BUILD_DIR)/.resolved-$(MACH): $(DEPENDED)
269 $(PKGDEPEND) resolve $(EXTDEPFILES:%=-e %) -m $(DEPENDED)
270 $(TOUCH) $@
272 # lint the manifests all at once
273 $(BUILD_DIR)/.linted-$(MACH): $(BUILD_DIR)/.resolved-$(MACH)
274 @echo "VALIDATING MANIFEST CONTENT: $(RESOLVED)"
275 $(ENV) PYTHONPATH=$(WS_TOOLS)/python PROTO_PATH="$(PKG_PROTO_DIRS)"\
276 $(PKGLINT) $(CANONICAL_REPO:%=-c $(WS_LINT_CACHE)) \
277 -f $(WS_TOOLS)/pkglintrc $(RESOLVED)
278 $(TOUCH) $@
280 lintme: FRC
281 @echo "VALIDATING MANIFEST CONTENT: $(RESOLVED)"
282 $(ENV) PYTHONPATH=$(WS_TOOLS)/python PROTO_PATH="$(PKG_PROTO_DIRS)"\
283 $(PKGLINT) $(CANONICAL_REPO:%=-c $(WS_LINT_CACHE)) \
284 -f $(WS_TOOLS)/pkglintrc $(RESOLVED)
286 FRC:
289 # published
290 PKGSEND_PUBLISH_OPTIONS = -s $(WS_REPO) publish --fmri-in-manifest
291 PKGSEND_PUBLISH_OPTIONS += $(PKG_PROTO_DIRS:%=-d %)
292 PKGSEND_PUBLISH_OPTIONS += -T \*.py
293 $(MANIFEST_BASE)-%.published: $(MANIFEST_BASE)-%.depend.res $(BUILD_DIR)/.linted-$(MACH)
294 $(PKGSEND) $(PKGSEND_PUBLISH_OPTIONS) $<
295 $(PKGFMT) <$< >$@
297 $(BUILD_DIR)/.published-$(MACH): $(PUBLISHED)
298 $(TOUCH) $@
300 print-package-names: canonical-manifests
301 @cat $(VERSIONED_MANIFESTS) $(WS_TOP)/transforms/print-pkgs | \
302 $(PKGMOGRIFY) $(PKG_OPTIONS) /dev/fd/0 | \
303 sed -e '/^$$/d' -e '/^#.*$$/d' | sort -u
305 print-package-paths: canonical-manifests
306 @cat $(VERSIONED_MANIFESTS) $(WS_TOP)/transforms/print-paths | \
307 $(PKGMOGRIFY) $(PKG_OPTIONS) /dev/fd/0 | \
308 sed -e '/^$$/d' -e '/^#.*$$/d' | sort -u
310 install-packages: publish
311 @if [ $(IS_GLOBAL_ZONE) = 0 -o x$(ROOT) != x ]; then \
312 cat $(VERSIONED_MANIFESTS) $(WS_TOP)/transforms/print-paths | \
313 $(PKGMOGRIFY) $(PKG_OPTIONS) /dev/fd/0 | \
314 sed -e '/^$$/d' -e '/^#.*$$/d' -e 's;/;;' | sort -u | \
315 (cd $(PROTO_DIR) ; pfexec /bin/cpio -dump $(ROOT)) ; \
316 else ; \
317 echo "unsafe to install package(s) automatically" ; \
320 $(RESOLVED): install
322 canonical-manifests: $(CANONICAL_MANIFESTS) Makefile $(PATCHES)
323 ifeq ($(strip $(CANONICAL_MANIFESTS)),)
324 # If there were no canonical manifests in the workspace, nothing will
325 # be published and we should fail. A sample manifest can be generated
326 # with
327 # $ gmake sample-manifest
328 # Once created, it will need to be reviewed, edited, and added to the
329 # workspace.
330 $(error Missing canonical manifest(s))
331 endif
333 # This converts required paths to containing package names for be able to
334 # properly setup the build environment for a component.
335 required-pkgs.mk: Makefile
336 @echo "generating $@ from Makefile REQUIRED_* data"
337 @pkg search -H -l '<$(DEPENDS:%=% OR) /bin/true>' \
338 | sed -e 's/pkg:\/\(.*\)@.*/REQUIRED_PKGS += \1/g' >$@
340 pre-prep: required-pkgs.mk
343 CLEAN_PATHS += required-pkgs.mk