1 # $Id: dpadd.mk,v 1.30 2021/12/08 05:56:50 sjg Exp $
3 # @(#) Copyright (c) 2004, Simon J. Gerraty
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
12 # Please send copies of changes and bug-fixes to:
18 # This makefile manages a number of variables that simplify
19 # dealing with libs in a build.
21 # Primary inputs are DPLIBS, DPADD and SRC_LIBS:
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
29 # DPADD List of LIB* that should already be built.
32 # List of LIB* that we want headers from, we do *not*
33 # require that such libs have been built.
35 # The above all get added to DPMAGIC_LIBS which is what we
38 # We expect LIB* to be set to absolute path of a library -
39 # suitable for putting in DPADD.
42 # LIBC ?= ${OBJTOP}/lib/libc/libc.a
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):
50 # What should be added to LDADD (eg -lc)
53 # This is trivial - just the dirname of the built library.
56 # Where the src for ${__lib} is, if LIB* is set as above
57 # we can simply substitute ${SRCTOP} for ${OBJTOP} in
60 # INCLUDES_${__lib:T:R}:
61 # What should be added to CFLAGS
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.
67 # Otherwise default will be -I${OBJ_${__lib:T:R}}
68 # -I${SRC_${__lib:T:R}}
70 # Note much of the above is skipped for staged libs
72 # LIBC ?= ${STAGE_OBJTOP}/usr/lib/libc.a
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.
79 .if !target(__${.PARSEFILE}__)
80 __${.PARSEFILE}__: .NOTMAIN
82 # sometimes we play games with .CURDIR etc
83 # _* hold the original values of .*
87 .if ${_CURDIR} == ${SRCTOP}
91 RELDIR?= ${_CURDIR:S,${SRCTOP}/,,}
92 .if ${RELDIR} == ${_CURDIR}
93 RELDIR?= ${_OBJDIR:S,${OBJTOP}/,,}
95 RELTOP?= ${RELDIR:C,[^/]+,..,g}
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}
106 .ifdef CXXFLAGS_DEBUG_XTRA
107 CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
110 .-include <local.dpadd.mk>
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-*}" != ""
119 LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
123 # DPADD can contain things other than libs
124 __dpadd_libs := ${DPADD:M*/lib*}
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
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}}" == ""
141 # Last of all... for libc and libgcc
142 DPADD+= ${DPADD_LAST}
144 # de-dupuplicate __ldadd_all_xtras into __ldadd_xtras
145 # in reverse order so that libs end up listed after all that needed them.
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}
153 .if !empty(__ldadd_xtras)
154 # now back to the original order
155 __ldadd_xtras:= ${__ldadd_xtras:[-1..1]}
156 LDADD+= ${__ldadd_xtras}
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.
164 __dpadd_libs := ${DPADD:M*/lib*}
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}
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
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.
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}}@}
199 # we skip this for staged libs
200 .for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
202 # if SRC_libfoo is not set, then we assume that the srcdir corresponding
203 # to where we found the library is correct.
205 SRC_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELSRCTOP},}
207 # This is a no-brainer but just to be complete...
209 OBJ_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELOBJTOP},}
211 # If INCLUDES_libfoo is not set, then we'll use ${SRC_libfoo}/h if it exists,
212 # else just ${SRC_libfoo}.
214 .if !empty(SRC_${__lib:T:R})
215 INCLUDES_${__lib:T:R} ?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
219 # even for staged libs we sometimes
220 # need to allow direct -I to avoid cicular dependencies
221 .for __lib in ${DPMAGIC_LIBS:O:u:T:R}
222 .if !empty(SRC_${__lib}) && empty(INCLUDES_${__lib})
223 # must be a staged lib
224 .if exists(${SRC_${__lib}}/h)
225 INCLUDES_${__lib} = -I${SRC_${__lib}}/h
227 INCLUDES_${__lib} = -I${SRC_${__lib}}
232 # when linking a shared lib, avoid non pic libs
233 SHLDADD+= ${LDADD:N-[lL]*}
234 .for __lib in ${__dpadd_libs:u}
235 .if defined(SHLIB_NAME) && ${LDADD:M-l${__lib:T:R:S,lib,,}} != ""
236 .if ${__lib:T:N*_pic.a:N*.so} == "" || exists(${__lib:R}.so)
237 SHLDADD+= -l${__lib:T:R:S,lib,,}
238 .elif exists(${__lib:R}_pic.a)
239 SHLDADD+= -l${__lib:T:R:S,lib,,}_pic
241 .warning ${RELDIR}.${TARGET_SPEC} needs ${__lib:T:R}_pic.a
242 SHLDADD+= -l${__lib:T:R:S,lib,,}
244 SHLDADD+= -L${__lib:H}
248 # Now for the bits we actually need
250 .for __lib in ${__dpadd_libs:u}
251 .if (make(${PROG}_p) || defined(NEED_GPROF)) && exists(${__lib:R}_p.a)
252 __ldadd=-l${__lib:T:R:S,lib,,}
253 LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
258 # We take care of duplicate suppression later.
259 # don't apply :T:R too early
260 __dpadd_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_${x:T:R}}@}
261 __dpadd_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_${x:T:R}}@}
263 __dpadd_last_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_LAST_${x:T:R}}@}
264 __dpadd_last_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_LAST_${x:T:R}}@}
266 .if defined(HOSTPROG) || ${MACHINE:Nhost*} == ""
267 # we want any -I/usr/* last
268 __dpadd_last_incs := \
269 ${__dpadd_last_incs:N-I/usr/*} \
270 ${__dpadd_incs:M-I/usr/*} \
271 ${__dpadd_last_incs:M-I/usr/*}
272 __dpadd_incs := ${__dpadd_incs:N-I/usr/*}
276 # eliminate any duplicates - but don't mess with the order
277 # force evaluation now - to avoid giving make a headache
279 .for t in CFLAGS CXXFLAGS
281 __$t_incs:=${$t:M-I*:O:u}
282 .for i in ${__dpadd_incs}
283 .if "${__$t_incs:M$i}" == ""
290 .for t in CFLAGS_LAST CXXFLAGS_LAST
292 __$t_incs:=${$t:M-I*:u}
293 .for i in ${__dpadd_last_incs}
294 .if "${__$t_incs:M$i}" == ""
301 # This target is used to gather a list of
307 .if defined(DPADD) && ${DPADD} != ""
308 @echo "${RELDIR}: ${DPADD:S,${OBJTOP}/,,}"
314 # We don't want to assume that we need to .PATH every element of
315 # SRC_LIBS, but the Makefile cannot do
316 # .PATH: ${SRC_libfoo}
317 # since the value of SRC_libfoo must be available at the time .PATH:
318 # is read - and we only just worked it out.
319 # Further, they can't wait until after include of {lib,prog}.mk as
320 # the .PATH is needed before then.
321 # So we let the Makefile do
322 # SRC_PATHADD+= ${SRC_libfoo}
323 # and we defer the .PATH: until now so that SRC_libfoo will be available.
324 .PATH: ${SRC_PATHADD}
327 # after all that, if doing -n we don't care
328 .if ${.MAKEFLAGS:Ux:M-n} != ""
330 .elif ${.MAKE.MODE:Mmeta*} != "" && exists(${.MAKE.DEPENDFILE})
331 DPADD_CLEAR_DPADD ?= yes
332 .if ${DPADD_CLEAR_DPADD} == "yes"
334 __dpadd_libs := ${__dpadd_libs}
335 # we have made what use of it we can of DPADD