dpadd.mk (a34d5fb1) dpadd.mk (6a91b982)
1# $Id: dpadd.mk,v 1.28 2020/08/19 17:51:53 sjg Exp $
1# $Id: dpadd.mk,v 1.19 2014/04/05 22:56:54 sjg Exp $
2#
3# @(#) Copyright (c) 2004, Simon J. Gerraty
4#
5# This file is provided in the hope that it will
6# be of use. There is absolutely NO WARRANTY.
7# Permission to copy, redistribute or otherwise
2#
3# @(#) Copyright (c) 2004, Simon J. Gerraty
4#
5# This file is provided in the hope that it will
6# be of use. There is absolutely NO WARRANTY.
7# Permission to copy, redistribute or otherwise
8# use this file is hereby granted provided that
8# use this file is hereby granted provided that
9# the above copyright notice and this notice are
9# the above copyright notice and this notice are
10# left intact.
11#
10# left intact.
11#
12# Please send copies of changes and bug-fixes to:
13# sjg@crufty.net
14#
15
12# Please send copies of changes and bug-fixes to:
13# sjg@crufty.net
14#
15
16##
17# DESCRIPTION:
18# This makefile manages a number of variables that simplify
19# dealing with libs in a build.
20#
21# Primary inputs are DPLIBS, DPADD and SRC_LIBS:
22#
23# DPLIBS
24# List of LIB* that we will actually link with
25# should be in correct link order.
26# DPLIBS is a short-cut to ensure that DPADD and LDADD are
27# kept in sync.
28#
29# DPADD List of LIB* that should already be built.
30#
31# SRC_LIBS
32# List of LIB* that we want headers from, we do *not*
33# require that such libs have been built.
34#
35# The above all get added to DPMAGIC_LIBS which is what we
36# process.
37#
38# We expect LIB* to be set to absolute path of a library -
39# suitable for putting in DPADD.
40# eg.
41#
42# LIBC ?= ${OBJTOP}/lib/libc/libc.a
43#
44# From such a path we can derrive a number of other variables
45# for which we can supply sensible default values.
46# We name all these variables for the basename of the library
47# (libc in our example above -- ${__lib:T:R} in below):
48#
49# LDADD_${__lib:T:R}:
50# What should be added to LDADD (eg -lc)
51#
52# OBJ_${__lib:T:R}:
53# This is trivial - just the dirname of the built library.
54#
55# SRC_${__lib:T:R}:
56# Where the src for ${__lib} is, if LIB* is set as above
57# we can simply substitute ${SRCTOP} for ${OBJTOP} in
58# the dirname.
59#
60# INCLUDES_${__lib:T:R}:
61# What should be added to CFLAGS
62#
63# If the directory ${SRC_${__lib:T:R}}/h exists we will
64# only add -I${SRC_${__lib:T:R}}/h on the basis that
65# this is where the public api is kept.
66#
67# Otherwise default will be -I${OBJ_${__lib:T:R}}
68# -I${SRC_${__lib:T:R}}
69#
70# Note much of the above is skipped for staged libs
71# eg.
72# LIBC ?= ${STAGE_OBJTOP}/usr/lib/libc.a
73#
74# Since we can safely assume that -I${STAGE_OBJTOP}/usr/include
75# and -L${STAGE_OBJTOP}/usr/lib are sufficient, and we should
76# have no need of anything else.
77#
78
79.if !target(__${.PARSEFILE}__)
80__${.PARSEFILE}__:
81
82# sometimes we play games with .CURDIR etc
83# _* hold the original values of .*
84_OBJDIR?= ${.OBJDIR}
85_CURDIR?= ${.CURDIR}
86
16.if !target(__${.PARSEFILE}__)
17__${.PARSEFILE}__:
18
19# sometimes we play games with .CURDIR etc
20# _* hold the original values of .*
21_OBJDIR?= ${.OBJDIR}
22_CURDIR?= ${.CURDIR}
23
87.if ${_CURDIR} == ${SRCTOP}
88RELDIR=.
89RELTOP=.
90.else
91RELDIR?= ${_CURDIR:S,${SRCTOP}/,,}
92.if ${RELDIR} == ${_CURDIR}
93RELDIR?= ${_OBJDIR:S,${OBJTOP}/,,}
94.endif
95RELTOP?= ${RELDIR:C,[^/]+,..,g}
96.endif
97RELOBJTOP?= ${OBJTOP}
98RELSRCTOP?= ${SRCTOP}
99
100# we get included just about everywhere so this is handy...
101# C*DEBUG_XTRA are for defining on cmd line etc
102# so do not use in makefiles.
103.ifdef CFLAGS_DEBUG_XTRA
104CFLAGS_LAST += ${CFLAGS_DEBUG_XTRA}
105.endif
106.ifdef CXXFLAGS_DEBUG_XTRA
107CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
108.endif
109
110.-include <local.dpadd.mk>
111
112# DPLIBS helps us ensure we keep DPADD and LDADD in sync
113DPLIBS+= ${DPLIBS_LAST}
24# DPLIBS helps us ensure we keep DPADD and LDADD in sync
25DPLIBS+= ${DPLIBS_LAST}
114DPADD+= ${DPLIBS:N-*}
115.for __lib in ${DPLIBS}
116.if "${__lib:M-*}" != ""
117LDADD += ${__lib}
118.else
119LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
120.endif
26DPADD+= ${DPLIBS}
27.for __lib in ${DPLIBS:T:R}
28LDADD+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
121.endfor
122
123# DPADD can contain things other than libs
29.endfor
30
31# DPADD can contain things other than libs
124__dpadd_libs := ${DPADD:M*/lib*}
32__dpadd_libs = ${DPADD:M*/lib*}
125
33
126.if defined(PROG) && ${MK_PROG_LDORDER_MK:Uno} != "no"
127# some libs have dependencies...
128# DPLIBS_* allows bsd.libnames.mk to flag libs which must be included
129# in DPADD for a given library.
34# some libs have dependencies...
35# DPLIBS_* allows bsd.libnames.mk to flag libs which must be included
36# in DPADD for a given library.
130# Gather all such dependencies into __ldadd_all_xtras
131# dups will be dealt with later.
132# Note: libfoo_pic uses DPLIBS_libfoo
133__ldadd_all_xtras=
134.for __lib in ${__dpadd_libs:@d@${DPLIBS_${d:T:R:S,_pic,,}}@}
135__ldadd_all_xtras+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
37.for __lib in ${__dpadd_libs:@d@${DPLIBS_${d:T:R}}@}
136.if "${DPADD:M${__lib}}" == ""
137DPADD+= ${__lib}
38.if "${DPADD:M${__lib}}" == ""
39DPADD+= ${__lib}
40LDADD+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
138.endif
139.endfor
41.endif
42.endfor
140.endif
141# Last of all... for libc and libgcc
142DPADD+= ${DPADD_LAST}
143
43# Last of all... for libc and libgcc
44DPADD+= ${DPADD_LAST}
45
144# de-dupuplicate __ldadd_all_xtras into __ldadd_xtras
145# in reverse order so that libs end up listed after all that needed them.
146__ldadd_xtras=
147.for __lib in ${__ldadd_all_xtras:[-1..1]}
148.if "${__ldadd_xtras:M${__lib}}" == "" || ${NEED_IMPLICIT_LDADD:tl:Uno} != "no"
149__ldadd_xtras+= ${__lib}
150.endif
151.endfor
152
153.if !empty(__ldadd_xtras)
154# now back to the original order
155__ldadd_xtras:= ${__ldadd_xtras:[-1..1]}
156LDADD+= ${__ldadd_xtras}
157.endif
158
159# Convert DPADD into -I and -L options and add them to CPPFLAGS and LDADD
160# For the -I's convert the path to a relative one. For separate objdirs
161# the DPADD paths will be to the obj tree so we need to subst anyway.
162
46# Convert DPADD into -I and -L options and add them to CPPFLAGS and LDADD
47# For the -I's convert the path to a relative one. For separate objdirs
48# the DPADD paths will be to the obj tree so we need to subst anyway.
49
163# update this
164__dpadd_libs := ${DPADD:M*/lib*}
50# If USE_PROFILE is yes, then check for profiled versions of libs
51# and use them.
165
52
53USE_PROFILE?=no
54.if defined(LIBDL) && exists(${LIBDL})
55.if defined(PROG) && (make(${PROG}_p) || ${USE_PROFILE} == yes) && \
56 defined(LDFLAGS) && ${LDFLAGS:M-export-dynamic}
57# building profiled version of a prog that needs dlopen to work
58DPLIBS+= ${LIBDL}
59.endif
60.endif
61
62.if defined(LIBDMALLOC) && exists(${LIBDMALLOC})
63.if defined(USE_DMALLOC) && ${USE_DMALLOC} != no
64.if !defined(NO_DMALLOC)
65CPPFLAGS+= -DUSE_DMALLOC
66.endif
67DPLIBS+= ${LIBDMALLOC}
68.endif
69.endif
70
166# Order -L's to search ours first.
167# Avoids picking up old versions already installed.
168__dpadd_libdirs := ${__dpadd_libs:R:H:S/^/-L/g:O:u:N-L}
169LDADD += ${__dpadd_libdirs:M-L${OBJTOP}/*}
71# Order -L's to search ours first.
72# Avoids picking up old versions already installed.
73__dpadd_libdirs := ${__dpadd_libs:R:H:S/^/-L/g:O:u:N-L}
74LDADD += ${__dpadd_libdirs:M-L${OBJTOP}/*}
170LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*:N-L${HOST_LIBDIR:U/usr/lib}}
171.if defined(HOST_LIBDIR) && ${HOST_LIBDIR} != "/usr/lib"
172LDADD+= -L${HOST_LIBDIR}
75LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*}
76
77.if ${.CURDIR} == ${SRCTOP}
78RELDIR=.
79RELTOP=.
80.else
81RELDIR?= ${.CURDIR:S,${SRCTOP}/,,}
82.if ${RELDIR} == ${.CURDIR}
83RELDIR?= ${.OBJDIR:S,${OBJTOP}/,,}
173.endif
84.endif
85RELTOP?= ${RELDIR:C,[^/]+,..,g}
86.endif
87RELOBJTOP?= ${OBJTOP}
88RELSRCTOP?= ${SRCTOP}
174
175.if !make(dpadd)
176.ifdef LIB
177# Each lib is its own src_lib, we want to include it in SRC_LIBS
178# so that the correct INCLUDES_* will be picked up automatically.
179SRC_LIBS+= ${_OBJDIR}/lib${LIB}.a
180.endif
181.endif
182
89
90.if !make(dpadd)
91.ifdef LIB
92# Each lib is its own src_lib, we want to include it in SRC_LIBS
93# so that the correct INCLUDES_* will be picked up automatically.
94SRC_LIBS+= ${_OBJDIR}/lib${LIB}.a
95.endif
96.endif
97
183#
98#
184# This little bit of magic, assumes that SRC_libfoo will be
185# set if it cannot be correctly derrived from ${LIBFOO}
186# Note that SRC_libfoo and INCLUDES_libfoo should be named for the
187# actual library name not the variable name that might refer to it.
188# 99% of the time the two are the same, but the DPADD logic
189# only has the library name available, so stick to that.
99# This little bit of magic, assumes that SRC_libfoo will be
100# set if it cannot be correctly derrived from ${LIBFOO}
101# Note that SRC_libfoo and INCLUDES_libfoo should be named for the
102# actual library name not the variable name that might refer to it.
103# 99% of the time the two are the same, but the DPADD logic
104# only has the library name available, so stick to that.
190#
105#
191
192SRC_LIBS?=
106
107SRC_LIBS?=
193# magic_libs includes those we want to link with
194# as well as those we might look at
195__dpadd_magic_libs += ${__dpadd_libs} ${SRC_LIBS}
196DPMAGIC_LIBS += ${__dpadd_magic_libs} \
197 ${__dpadd_magic_libs:@d@${DPMAGIC_LIBS_${d:T:R}}@}
108__dpadd_libs += ${SRC_LIBS}
109DPMAGIC_LIBS += ${__dpadd_libs} \
110 ${__dpadd_libs:@d@${DPMAGIC_LIBS_${d:T:R}}@}
198
111
199# we skip this for staged libs
200.for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
201#
112.for __lib in ${DPMAGIC_LIBS:O:u}
113#
202# if SRC_libfoo is not set, then we assume that the srcdir corresponding
203# to where we found the library is correct.
204#
205SRC_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELSRCTOP},}
206#
207# This is a no-brainer but just to be complete...
208#
209OBJ_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELOBJTOP},}
210#
211# If INCLUDES_libfoo is not set, then we'll use ${SRC_libfoo}/h if it exists,
212# else just ${SRC_libfoo}.
213#
214INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
215
216.endfor
217
114# if SRC_libfoo is not set, then we assume that the srcdir corresponding
115# to where we found the library is correct.
116#
117SRC_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELSRCTOP},}
118#
119# This is a no-brainer but just to be complete...
120#
121OBJ_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELOBJTOP},}
122#
123# If INCLUDES_libfoo is not set, then we'll use ${SRC_libfoo}/h if it exists,
124# else just ${SRC_libfoo}.
125#
126INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
127
128.endfor
129
218# even for staged libs we sometimes
219# need to allow direct -I to avoid cicular dependencies
220.for __lib in ${DPMAGIC_LIBS:O:u:T:R}
221.if !empty(SRC_${__lib}) && empty(INCLUDES_${__lib})
222# must be a staged lib
223.if exists(${SRC_${__lib}}/h)
224INCLUDES_${__lib} = -I${SRC_${__lib}}/h
225.else
226INCLUDES_${__lib} = -I${SRC_${__lib}}
227.endif
228.endif
229.endfor
230
231# when linking a shared lib, avoid non pic libs
232SHLDADD+= ${LDADD:N-[lL]*}
233.for __lib in ${__dpadd_libs:u}
234.if defined(SHLIB_NAME) && ${LDADD:M-l${__lib:T:R:S,lib,,}} != ""
235.if ${__lib:T:N*_pic.a:N*.so} == "" || exists(${__lib:R}.so)
236SHLDADD+= -l${__lib:T:R:S,lib,,}
237.elif exists(${__lib:R}_pic.a)
238SHLDADD+= -l${__lib:T:R:S,lib,,}_pic
239.else
240.warning ${RELDIR}.${TARGET_SPEC} needs ${__lib:T:R}_pic.a
241SHLDADD+= -l${__lib:T:R:S,lib,,}
242.endif
243SHLDADD+= -L${__lib:H}
244.endif
245.endfor
246
247# Now for the bits we actually need
248__dpadd_incs=
249.for __lib in ${__dpadd_libs:u}
250.if (make(${PROG}_p) || defined(NEED_GPROF)) && exists(${__lib:R}_p.a)
251__ldadd=-l${__lib:T:R:S,lib,,}
252LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
253.endif
130# Now for the bits we actually need
131__dpadd_incs=
132.for __lib in ${__dpadd_libs:u}
133.if (make(${PROG}_p) || defined(NEED_GPROF)) && exists(${__lib:R}_p.a)
134__ldadd=-l${__lib:T:R:S,lib,,}
135LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
136.endif
254.endfor
255
256#
137
138#
139# Some libs generate headers, so we potentially need both
140# the src dir and the obj dir.
141# If ${INCLUDES_libfoo} contains a word ending in /h, we assume that either
142# 1. it does not generate headers or
143# 2. INCLUDES_libfoo will have been set correctly
144# XXX it gets ugly avoiding duplicates...
145# use :? to ensure .for does not prevent correct evaluation
146#
257# We take care of duplicate suppression later.
147# We take care of duplicate suppression later.
258# don't apply :T:R too early
259__dpadd_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_${x:T:R}}@}
260__dpadd_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_${x:T:R}}@}
148__dpadd_incs += ${"${INCLUDES_${__lib:T:R}:M*/h}":? :-I${OBJ_${__lib:T:R}}}
149__dpadd_incs += ${INCLUDES_${__lib:T:R}}
150.endfor
261
151
262__dpadd_last_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_LAST_${x:T:R}}@}
263__dpadd_last_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_LAST_${x:T:R}}@}
264
265.if defined(HOSTPROG) || ${MACHINE:Nhost*} == ""
266# we want any -I/usr/* last
267__dpadd_last_incs := \
268 ${__dpadd_last_incs:N-I/usr/*} \
269 ${__dpadd_incs:M-I/usr/*} \
270 ${__dpadd_last_incs:M-I/usr/*}
271__dpadd_incs := ${__dpadd_incs:N-I/usr/*}
272.endif
273
274#
275# eliminate any duplicates - but don't mess with the order
276# force evaluation now - to avoid giving make a headache
277#
278.for t in CFLAGS CXXFLAGS
279# avoid duplicates
280__$t_incs:=${$t:M-I*:O:u}
281.for i in ${__dpadd_incs}
282.if "${__$t_incs:M$i}" == ""
283$t+= $i
284__$t_incs+= $i
285.endif
286.endfor
287.endfor
288
152#
153# eliminate any duplicates - but don't mess with the order
154# force evaluation now - to avoid giving make a headache
155#
156.for t in CFLAGS CXXFLAGS
157# avoid duplicates
158__$t_incs:=${$t:M-I*:O:u}
159.for i in ${__dpadd_incs}
160.if "${__$t_incs:M$i}" == ""
161$t+= $i
162__$t_incs+= $i
163.endif
164.endfor
165.endfor
166
289.for t in CFLAGS_LAST CXXFLAGS_LAST
290# avoid duplicates
291__$t_incs:=${$t:M-I*:u}
292.for i in ${__dpadd_last_incs}
293.if "${__$t_incs:M$i}" == ""
294$t+= $i
295__$t_incs+= $i
296.endif
297.endfor
298.endfor
299
300# This target is used to gather a list of
301# dir: ${DPADD}
302# entries
303.if make(*dpadd*)
167# This target is used to gather a list of
168# dir: ${DPADD}
169# entries
170.if make(*dpadd*)
171# allow overrides
172.-include "dpadd++.mk"
173
304.if !target(dpadd)
305dpadd: .NOTMAIN
306.if defined(DPADD) && ${DPADD} != ""
307 @echo "${RELDIR}: ${DPADD:S,${OBJTOP}/,,}"
308.endif
309.endif
310.endif
311
312.ifdef SRC_PATHADD
174.if !target(dpadd)
175dpadd: .NOTMAIN
176.if defined(DPADD) && ${DPADD} != ""
177 @echo "${RELDIR}: ${DPADD:S,${OBJTOP}/,,}"
178.endif
179.endif
180.endif
181
182.ifdef SRC_PATHADD
313# We don't want to assume that we need to .PATH every element of
183# We don't want to assume that we need to .PATH every element of
314# SRC_LIBS, but the Makefile cannot do
315# .PATH: ${SRC_libfoo}
316# since the value of SRC_libfoo must be available at the time .PATH:
184# SRC_LIBS, but the Makefile cannot do
185# .PATH: ${SRC_libfoo}
186# since the value of SRC_libfoo must be available at the time .PATH:
317# is read - and we only just worked it out.
318# Further, they can't wait until after include of {lib,prog}.mk as
187# is read - and we only just worked it out.
188# Further, they can't wait until after include of {lib,prog}.mk as
319# the .PATH is needed before then.
320# So we let the Makefile do
321# SRC_PATHADD+= ${SRC_libfoo}
322# and we defer the .PATH: until now so that SRC_libfoo will be available.
323.PATH: ${SRC_PATHADD}
324.endif
325
189# the .PATH is needed before then.
190# So we let the Makefile do
191# SRC_PATHADD+= ${SRC_libfoo}
192# and we defer the .PATH: until now so that SRC_libfoo will be available.
193.PATH: ${SRC_PATHADD}
194.endif
195
326# after all that, if doing -n we don't care
327.if ${.MAKEFLAGS:Ux:M-n} != ""
328DPADD =
329.elif ${.MAKE.MODE:Mmeta*} != "" && exists(${.MAKE.DEPENDFILE})
330DPADD_CLEAR_DPADD ?= yes
331.if ${DPADD_CLEAR_DPADD} == "yes"
332# save this
333__dpadd_libs := ${__dpadd_libs}
334# we have made what use of it we can of DPADD
335DPADD =
336.endif
196.endif
337.endif
338
339.endif