]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/mk/dpadd.mk
Update to bmake-20200902
[FreeBSD/FreeBSD.git] / contrib / bmake / mk / dpadd.mk
1 # $Id: dpadd.mk,v 1.28 2020/08/19 17:51:53 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
8 #       use this file is hereby granted provided that
9 #       the above copyright notice and this notice are
10 #       left intact.
11 #
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
87 .if ${_CURDIR} == ${SRCTOP}
88 RELDIR=.
89 RELTOP=.
90 .else
91 RELDIR?= ${_CURDIR:S,${SRCTOP}/,,}
92 .if ${RELDIR} == ${_CURDIR}
93 RELDIR?= ${_OBJDIR:S,${OBJTOP}/,,}
94 .endif
95 RELTOP?= ${RELDIR:C,[^/]+,..,g}
96 .endif
97 RELOBJTOP?= ${OBJTOP}
98 RELSRCTOP?= ${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
104 CFLAGS_LAST += ${CFLAGS_DEBUG_XTRA}
105 .endif
106 .ifdef CXXFLAGS_DEBUG_XTRA
107 CXXFLAGS_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
113 DPLIBS+= ${DPLIBS_LAST}
114 DPADD+= ${DPLIBS:N-*}
115 .for __lib in ${DPLIBS}
116 .if "${__lib:M-*}" != ""
117 LDADD += ${__lib}
118 .else
119 LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
120 .endif
121 .endfor
122
123 # DPADD can contain things other than libs
124 __dpadd_libs := ${DPADD:M*/lib*}
125
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.
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.*//}}
136 .if "${DPADD:M${__lib}}" == ""
137 DPADD+= ${__lib}
138 .endif
139 .endfor
140 .endif
141 # Last of all... for libc and libgcc
142 DPADD+= ${DPADD_LAST}
143
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]}
156 LDADD+= ${__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
163 # update this
164 __dpadd_libs := ${DPADD:M*/lib*}
165
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}
169 LDADD += ${__dpadd_libdirs:M-L${OBJTOP}/*}
170 LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*:N-L${HOST_LIBDIR:U/usr/lib}}
171 .if defined(HOST_LIBDIR) && ${HOST_LIBDIR} != "/usr/lib"
172 LDADD+= -L${HOST_LIBDIR}
173 .endif
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.
179 SRC_LIBS+= ${_OBJDIR}/lib${LIB}.a
180 .endif
181 .endif
182
183 #
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.
190 #
191
192 SRC_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}
196 DPMAGIC_LIBS += ${__dpadd_magic_libs} \
197         ${__dpadd_magic_libs:@d@${DPMAGIC_LIBS_${d:T:R}}@}
198
199 # we skip this for staged libs
200 .for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
201 #
202 # if SRC_libfoo is not set, then we assume that the srcdir corresponding
203 # to where we found the library is correct.
204 #
205 SRC_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELSRCTOP},}
206 #
207 # This is a no-brainer but just to be complete...
208 #
209 OBJ_${__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 #
214 INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
215
216 .endfor
217
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)
224 INCLUDES_${__lib} = -I${SRC_${__lib}}/h
225 .else
226 INCLUDES_${__lib} = -I${SRC_${__lib}}
227 .endif
228 .endif
229 .endfor
230
231 # when linking a shared lib, avoid non pic libs
232 SHLDADD+= ${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)
236 SHLDADD+= -l${__lib:T:R:S,lib,,}
237 .elif exists(${__lib:R}_pic.a)
238 SHLDADD+= -l${__lib:T:R:S,lib,,}_pic
239 .else
240 .warning ${RELDIR}.${TARGET_SPEC} needs ${__lib:T:R}_pic.a
241 SHLDADD+= -l${__lib:T:R:S,lib,,}
242 .endif
243 SHLDADD+= -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,,}
252 LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
253 .endif
254 .endfor
255
256 #
257 # 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}}@}
261
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
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*)
304 .if !target(dpadd)
305 dpadd:  .NOTMAIN
306 .if defined(DPADD) && ${DPADD} != ""
307         @echo "${RELDIR}: ${DPADD:S,${OBJTOP}/,,}"
308 .endif
309 .endif
310 .endif
311
312 .ifdef SRC_PATHADD
313 # 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:
317 # is read - and we only just worked it out.
318 # 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
326 # after all that, if doing -n we don't care
327 .if ${.MAKEFLAGS:Ux:M-n} != ""
328 DPADD =
329 .elif ${.MAKE.MODE:Mmeta*} != "" && exists(${.MAKE.DEPENDFILE})
330 DPADD_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
335 DPADD =
336 .endif
337 .endif
338
339 .endif