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