模式语法%.3:Automake中的man/libfoo.man具有不同的基名称



我编写了一个库libfoo,提供函数barbaz。我希望用户在调用man libfooman barman baz(类似于man fprintfman sprintf都指向同一页面(时能够找到相同的手册页(来自mans/libfoo.man(

我当前的设置有文件mans/libfoo.manMakefile.am

为了"告诉"automake我想以三个手册页结束,我指定了dist_man3_MANS变量。

Makefile.am:

dist_man3_MANS = mans/libfoo.3 mans/bar.3 mans/baz.3

来自GNU make,我想我可以写

%.3: mans/libfoo.man
ln -S libfoo.man $@

暂时创建链接,然后让Automake相应地安装这些链接,但Automake在Makefile.am:115: warning: '%'-style pattern rules are a GNU make extension中出错。我想正确地做这件事,并认真对待这个警告,不要依赖GNUMake尽可能地可移植。

Automake手册建议添加一个目标

.man.3:
$(LN_S) $^ $@

但这只是告诉Automakexx.man可以编译为xx.3,要求基本名称相同。我不想随身携带那些xx.man文件,所以这种方法不起作用。

我可以放一条规则破解它

dist_man3_MANS = mans/libfoo.3 mans/bar.3 mans/baz.3
$(dist_man3_MANS): mans/libfoo.man
$(LN_S) libfoo.man $@

但这似乎是一个肮脏的破解,因为我并没有给它一个将.man编译为.3的配方,而是说:";嘿,你可以用这个规则创建那些文件",在这种情况下,这可能是巧合。

我会按照Automake信息页面部分的例子扩展Automake规则,并按照的思路做一些事情

LIBFOO_MAN_ALIASES = bar baz
install-data-hook:
set -e; 
cd $(DESTDIR)$(man3dir) && 
for manalias in $(LIBFOO_MAN_ALIASES); do 
$(LN_S) libfoo.3 $${manalias}.3; 
done
uninstall-hook:
cd $(DESTDIR)$(man3dir) && 
for manalias in $(LIBFOO_MAN_ALIASES); do 
rm -f $${manalias}.3; 
done

依靠AC_PROG_LN_S来确保$(LN_S)为系统做一些合理的事情(符号链接、硬链接、副本(来创建一个可以被open(2)读取的文件名。

FTR,我刚刚看了三个不同系统的手册页,发现它们使用了三种不同的方法来使fprintf(3(手册页显示与printf(3(相同的手册页:

  • Debian 10使用符号链接

  • Fedora 35使用包含.so man3/printf.3的/usr/share/man/man3/fprintf.3文件(而其他一些手册页使用符号链接来实现相同的效果(

  • FreeBSD 13使用硬链接,而find /usr/share/man -type l在我相对干净的系统上找不到任何符号链接。然而,手动测试符号链接和.so man3/printf.3方法表明,FreeBSDman(1)没有以任何特殊的方式处理符号链接,因此打开了符号链接的手册页,它也像Fedora 35的man(1)一样解释.so命令。

我不知道这些方法的可移植性有多强。这三种方法中的每一种都可以通过使用适当的install-data-hookmake install上设置,但任何可以使用open(2)打开的man文件似乎都是有效的,因此$(LN_S)看起来是一个不错的选择。

最新更新