portconf 中的 .undef 功能

ports-mgmt/portconf 是個很棒的工具,它的用法就不多說了,google 一下都可以找到很多篇教學,這篇主要是幫 portconf 加入 .undef 的功能。

在 ports 中常常用到一個作法,就是利用 .ifdef 來判斷 WITHOUT_XXX 是否已定義,如果定義了,便加入 XXX 的設定,一個最常見的便是 WITHOUT_X11,對於那些不想裝 XWindow 的機器來說很有用,只需要在 ports.conf 加入:

*: WITHOUT_X11=yes    # WITHOUT_X11 也可

如此一來,所有的 ports 預設便會設定 WITHOUT_X11;但是對於某些套件來說,則必須去掉這個變數才能用到一些 library,最近遇到的例子是,我需要用到 textproc/wv,它 depend on x11-toolkits/gtk20,而 x11-toolkits/gtk20 depend on graphics/cairo,如果 cairo 設定 WITHOUT_X11 來編的話,gtk20 便會編不過出現:

gdkdrawable-x11.c:32:24: cairo-xlib.h: No such file or directory

所以 cairo 必須去掉 WITHOUT_X11 來重編。為了這些特定的套件的需要,我把 /usr/local/libexec/portconf 改成:

_conf=/usr/local/etc/ports.conf
if [ ! -r "${_conf}" ]; then
    exit
fi
_pwd=`pwd`
sed '/^#/d;/^[[:space:]]*$/d' "${_conf}" | while read _line; do
    for _port in ${_line%%:*}; do
        if [ "${_pwd%%${_port}}" != "${_pwd}" ]; then
            echo ${_line#*:} | sed -E 's/(!?)([A-Z0-9_]+)((\?)?=([^|]+))?/\1\2\4=\5/g;s/ *\| */|/g;s/ /%/g'
        fi
    done
done

至於 /etc/make.conf 裡 portconf 的設定改成(我的 /etc/make.conf 已經是改過的了):

# Begin portconf settings
# Do not touch these lines
_PORTSDIR!=/bin/realpath /usr/ports
_MATCHDIR!=echo `echo ${.CURDIR} | /usr/bin/grep ^${_PORTSDIR}`
.if !empty(_MATCHDIR) && exists(/usr/local/libexec/portconf)
_PORTCONF!=/usr/local/libexec/portconf
.for i in ${_PORTCONF:S/|/ /g}
${i:C/!([A-Z0-9_]+)(=([^ ]+)?)?/.undef \1/g}    # 主要是這行
${i:S/%/ /g}
.endfor
.endif
# End portconf settings

如此一來,我可以在 ports.conf 設定:

*: WITHOUT_X11=yes
graphics/cairo: !WITHOUT_X11

任何變數前面加上 ‘!’ 都會自動 .undef,以上面為例:

$ make -V _PORTCONF
WITHOUT_X11=yes !WITHOUT_X11=

最後會變成:

WITHOUT_X11=yes
.undef WITHOUT_X11

如此一來,便可針對某些套件設定相對於 Global 的設定了。
但要注意,不能寫成下面這樣:

graphics/cairo: !WITHOUT_X11
*: WITHOUT_X11=yes

否則會變成:

.undef WITHOUT_X11
WITHOUT_X11=yes

1 Responses to “portconf 中的 .undef 功能”


Leave a Reply