xref: /freebsd/contrib/bmake/mk/dpadd.mk (revision b9f654b163bce26de79705e77b872427c9f2afa1)
1# $Id: dpadd.mk,v 1.26 2018/02/12 21:54:26 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.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
24.if ${_CURDIR} == ${SRCTOP}
25RELDIR=.
26RELTOP=.
27.else
28RELDIR?= ${_CURDIR:S,${SRCTOP}/,,}
29.if ${RELDIR} == ${_CURDIR}
30RELDIR?= ${_OBJDIR:S,${OBJTOP}/,,}
31.endif
32RELTOP?= ${RELDIR:C,[^/]+,..,g}
33.endif
34RELOBJTOP?= ${OBJTOP}
35RELSRCTOP?= ${SRCTOP}
36
37# we get included just about everywhere so this is handy...
38# C*DEBUG_XTRA are for defining on cmd line etc
39# so do not use in makefiles.
40.ifdef CFLAGS_DEBUG_XTRA
41CFLAGS_LAST += ${CFLAGS_DEBUG_XTRA}
42.endif
43.ifdef CXXFLAGS_DEBUG_XTRA
44CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
45.endif
46
47.-include <local.dpadd.mk>
48
49# DPLIBS helps us ensure we keep DPADD and LDADD in sync
50DPLIBS+= ${DPLIBS_LAST}
51DPADD+= ${DPLIBS:N-*}
52.for __lib in ${DPLIBS}
53.if "${_lib:M-*}" != ""
54LDADD += ${__lib}
55.else
56LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
57.endif
58.endfor
59
60# DPADD can contain things other than libs
61__dpadd_libs := ${DPADD:M*/lib*}
62
63.if defined(PROG) && ${MK_PROG_LDORDER_MK:Uno} != "no"
64# some libs have dependencies...
65# DPLIBS_* allows bsd.libnames.mk to flag libs which must be included
66# in DPADD for a given library.
67# Gather all such dependencies into __ldadd_all_xtras
68# dups will be dealt with later.
69# Note: libfoo_pic uses DPLIBS_libfoo
70__ldadd_all_xtras=
71.for __lib in ${__dpadd_libs:@d@${DPLIBS_${d:T:R:S,_pic,,}}@}
72__ldadd_all_xtras+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
73.if "${DPADD:M${__lib}}" == ""
74DPADD+= ${__lib}
75.endif
76.endfor
77.endif
78# Last of all... for libc and libgcc
79DPADD+= ${DPADD_LAST}
80
81# de-dupuplicate __ldadd_all_xtras into __ldadd_xtras
82# in reverse order so that libs end up listed after all that needed them.
83__ldadd_xtras=
84.for __lib in ${__ldadd_all_xtras:[-1..1]}
85.if "${__ldadd_xtras:M${__lib}}" == "" || ${NEED_IMPLICIT_LDADD:tl:Uno} != "no"
86__ldadd_xtras+= ${__lib}
87.endif
88.endfor
89
90.if !empty(__ldadd_xtras)
91# now back to the original order
92__ldadd_xtras:= ${__ldadd_xtras:[-1..1]}
93LDADD+= ${__ldadd_xtras}
94.endif
95
96# Convert DPADD into -I and -L options and add them to CPPFLAGS and LDADD
97# For the -I's convert the path to a relative one.  For separate objdirs
98# the DPADD paths will be to the obj tree so we need to subst anyway.
99
100# update this
101__dpadd_libs := ${DPADD:M*/lib*}
102
103# Order -L's to search ours first.
104# Avoids picking up old versions already installed.
105__dpadd_libdirs := ${__dpadd_libs:R:H:S/^/-L/g:O:u:N-L}
106LDADD += ${__dpadd_libdirs:M-L${OBJTOP}/*}
107LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*:N-L${HOST_LIBDIR:U/usr/lib}}
108.if defined(HOST_LIBDIR) && ${HOST_LIBDIR} != "/usr/lib"
109LDADD+= -L${HOST_LIBDIR}
110.endif
111
112.if !make(dpadd)
113.ifdef LIB
114# Each lib is its own src_lib, we want to include it in SRC_LIBS
115# so that the correct INCLUDES_* will be picked up automatically.
116SRC_LIBS+= ${_OBJDIR}/lib${LIB}.a
117.endif
118.endif
119
120#
121# This little bit of magic, assumes that SRC_libfoo will be
122# set if it cannot be correctly derrived from ${LIBFOO}
123# Note that SRC_libfoo and INCLUDES_libfoo should be named for the
124# actual library name not the variable name that might refer to it.
125# 99% of the time the two are the same, but the DPADD logic
126# only has the library name available, so stick to that.
127#
128
129SRC_LIBS?=
130# magic_libs includes those we want to link with
131# as well as those we might look at
132__dpadd_magic_libs += ${__dpadd_libs} ${SRC_LIBS}
133DPMAGIC_LIBS += ${__dpadd_magic_libs} \
134	${__dpadd_magic_libs:@d@${DPMAGIC_LIBS_${d:T:R}}@}
135
136# we skip this for staged libs
137.for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
138#
139# if SRC_libfoo is not set, then we assume that the srcdir corresponding
140# to where we found the library is correct.
141#
142SRC_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELSRCTOP},}
143#
144# This is a no-brainer but just to be complete...
145#
146OBJ_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELOBJTOP},}
147#
148# If INCLUDES_libfoo is not set, then we'll use ${SRC_libfoo}/h if it exists,
149# else just ${SRC_libfoo}.
150#
151INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
152
153.endfor
154
155# even for staged libs we sometimes
156# need to allow direct -I to avoid cicular dependencies
157.for __lib in ${DPMAGIC_LIBS:O:u:T:R}
158.if !empty(SRC_${__lib}) && empty(INCLUDES_${__lib})
159# must be a staged lib
160.if exists(${SRC_${__lib}}/h)
161INCLUDES_${__lib} = -I${SRC_${__lib}}/h
162.else
163INCLUDES_${__lib} = -I${SRC_${__lib}}
164.endif
165.endif
166.endfor
167
168# when linking a shared lib, avoid non pic libs
169SHLDADD+= ${LDADD:N-[lL]*}
170.for __lib in ${__dpadd_libs:u}
171.if defined(SHLIB_NAME) && ${LDADD:M-l${__lib:T:R:S,lib,,}} != ""
172.if ${__lib:T:N*_pic.a:N*.so} == "" || exists(${__lib:R}.so)
173SHLDADD+= -l${__lib:T:R:S,lib,,}
174.elif exists(${__lib:R}_pic.a)
175SHLDADD+= -l${__lib:T:R:S,lib,,}_pic
176.else
177.warning ${RELDIR}.${TARGET_SPEC} needs ${__lib:T:R}_pic.a
178SHLDADD+= -l${__lib:T:R:S,lib,,}
179.endif
180SHLDADD+= -L${__lib:H}
181.endif
182.endfor
183
184# Now for the bits we actually need
185__dpadd_incs=
186.for __lib in ${__dpadd_libs:u}
187.if (make(${PROG}_p) || defined(NEED_GPROF)) && exists(${__lib:R}_p.a)
188__ldadd=-l${__lib:T:R:S,lib,,}
189LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
190.endif
191.endfor
192
193#
194# We take care of duplicate suppression later.
195# don't apply :T:R too early
196__dpadd_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_${x:T:R}}@}
197__dpadd_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_${x:T:R}}@}
198
199__dpadd_last_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_LAST_${x:T:R}}@}
200__dpadd_last_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_LAST_${x:T:R}}@}
201
202.if defined(HOSTPROG) || ${MACHINE:Nhost*} == ""
203# we want any -I/usr/* last
204__dpadd_last_incs := \
205	${__dpadd_last_incs:N-I/usr/*} \
206	${__dpadd_incs:M-I/usr/*} \
207	${__dpadd_last_incs:M-I/usr/*}
208__dpadd_incs := ${__dpadd_incs:N-I/usr/*}
209.endif
210
211#
212# eliminate any duplicates - but don't mess with the order
213# force evaluation now - to avoid giving make a headache
214#
215.for t in CFLAGS CXXFLAGS
216# avoid duplicates
217__$t_incs:=${$t:M-I*:O:u}
218.for i in ${__dpadd_incs}
219.if "${__$t_incs:M$i}" == ""
220$t+= $i
221__$t_incs+= $i
222.endif
223.endfor
224.endfor
225
226.for t in CFLAGS_LAST CXXFLAGS_LAST
227# avoid duplicates
228__$t_incs:=${$t:M-I*:u}
229.for i in ${__dpadd_last_incs}
230.if "${__$t_incs:M$i}" == ""
231$t+= $i
232__$t_incs+= $i
233.endif
234.endfor
235.endfor
236
237# This target is used to gather a list of
238# dir: ${DPADD}
239# entries
240.if make(*dpadd*)
241.if !target(dpadd)
242dpadd:	.NOTMAIN
243.if defined(DPADD) && ${DPADD} != ""
244	@echo "${RELDIR}: ${DPADD:S,${OBJTOP}/,,}"
245.endif
246.endif
247.endif
248
249.ifdef SRC_PATHADD
250# We don't want to assume that we need to .PATH every element of
251# SRC_LIBS, but the Makefile cannot do
252# .PATH: ${SRC_libfoo}
253# since the value of SRC_libfoo must be available at the time .PATH:
254# is read - and we only just worked it out.
255# Further, they can't wait until after include of {lib,prog}.mk as
256# the .PATH is needed before then.
257# So we let the Makefile do
258# SRC_PATHADD+= ${SRC_libfoo}
259# and we defer the .PATH: until now so that SRC_libfoo will be available.
260.PATH: ${SRC_PATHADD}
261.endif
262
263# after all that, if doing -n we don't care
264.if ${.MAKEFLAGS:Ux:M-n} != ""
265DPADD =
266.elif ${.MAKE.MODE:Mmeta*} != "" && exists(${.MAKE.DEPENDFILE})
267DPADD_CLEAR_DPADD ?= yes
268.if ${DPADD_CLEAR_DPADD} == "yes"
269# save this
270__dpadd_libs := ${__dpadd_libs}
271# we have made what use of it we can of DPADD
272DPADD =
273.endif
274.endif
275
276.endif
277