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
| |
| |