Makefile中的条件链接
在我的Makefile中,我只想链接到机器上安装的库。因此,例如,如果库是Makefile中的条件链接,makefile,linker,conditional,Makefile,Linker,Conditional,在我的Makefile中,我只想链接到机器上安装的库。因此,例如,如果库是hwloc,我想执行以下操作: xfoo : foo.o if (hwloc installed) gcc foo.o -o $@ -lhwloc else gcc foo.o -o $@ 有没有办法做这样的事?i、 e.是否可以检查是否安装了特定的库,并将其作为Makefile中的条件使用?以下是错误的答案: xfoo : foo.o if (hwloc installed);
hwloc
,我想执行以下操作:
xfoo : foo.o
if (hwloc installed)
gcc foo.o -o $@ -lhwloc
else
gcc foo.o -o $@
有没有办法做这样的事?i、 e.是否可以检查是否安装了特定的库,并将其作为Makefile中的条件使用?以下是错误的答案:
xfoo : foo.o
if (hwloc installed); then gcc foo.o -o $@ -lhwloc; else gcc foo.o -o $@; fi
从Makefile执行的命令不必只是简单的单个命令。shell可以执行的任何内容都可以从Makefile调用。包括整个脚本,夹在一行中
以下是正确答案:
然而,上述方法是错误的。你会发现很多自由软件包一直都在做这种事情:在一个库中有条件地链接,如果它可用的话
但它的实现方式是在运行make之前运行一个单独的configure
脚本。去抓取你选择的随机免费软件包的源代码tarball,阅读安装说明。它们都会告诉您在运行make
之前,首先运行configure
脚本
绝大多数自由软件包都使用GNU工具链来创建构建系统——configure
脚本和Makefile
。GNU工具链包括autoconf
和automake
工具(在许多情况下也是libtool
)。更多信息,请点击谷歌
还有一些其他的不太流行的工具链,但是GNU工具链是最常用的一个,用于这类事情。所以,要按照你想做的事情去做,通常的做法是:
在configure.ac
文件中:
AC_CHECK_LIB(hwloc,some_function_in_the_hwloc_library,[LINK_HWLOC=-lhwloc])
AC_SUBST(LINK_HWLOC)
hwloc_LDADD=@LINK_HWLOC@
在Makefile.am
文件中:
AC_CHECK_LIB(hwloc,some_function_in_the_hwloc_library,[LINK_HWLOC=-lhwloc])
AC_SUBST(LINK_HWLOC)
hwloc_LDADD=@LINK_HWLOC@
就这样。大多数自由软件包需要无数次这样做
autoconf
和automake
将负责编写实现此功能的shell脚本和makefile。如果您不想参与autotools/etc的话(虽然对于这样简单的事情,合理的解决方案也是合理的)而且你不想玩猜谜游戏,猜测人们可能在哪里安装了这个hwloc
库,那么你最好让人们手动打开这个功能
使用三(或四)个make变量<代码>使用HWLOC,HWLOC\u LDLIBS
,HWLOC\u CFLAGS
以及可能的HWLOC\u LDFLAGS
然后,当定义了USE\u HWLOC
时,您可以链接库,并使用其他三个变量,以防它们也被设置
ifdef USE_HWLOC
HWLOC:=-lhwloc
else
HWLOC:=
HWLOC_LDLIBS:=
HWLOC_LDFLAGS:=
HWLOC_CFLAGS:=
endif
xfoo : foo.o
gcc foo.o -o $@ $(HWLOC_LDLIBS) $(HWLOC)
我目前没有访问Linux机器的权限,所以请原谅,我的答案将未经测试 我将恭敬地反对我的两位前任 首先,使用自动工具修改现有的Makefile是一个坏主意。自动工具是为了避免在一个简单的用例中创建一个好的Makefile。这就像OP问“如何在我的Python脚本中将
+
更改为-
”,答案是“编写一个shell脚本来修改脚本,将其保存在临时文件中并执行该文件”
第二个答案是,当可以毫无痛苦地自动完成某件事时,为什么要手动完成
因此,正确答案是,这正是$(通配符)
的使用案例:
注意:库已安装或未提前安装,但未在构建期间制作。我无法理解使用模型-假设计算机上未安装heloc,哪个实体将解析其“引用”符号?这些引用符号将使用预处理器禁用。因此,foo.o对于这两种情况并不完全相同。很抱歉对这个简短的示例产生误解。值得考虑的另一个选择是让用户在Makefile顶部使用一个简单的变量来配置是否/如何链接hwloc。您能解释一下这是如何工作的吗?我不熟悉
$(通配符)
。是的。在此生成之前,库是否已安装。@Rakib很抱歉。。。请不要生气,但是,您现在必须去阅读手册,了解函数通配符
和patsubst
的工作原理。很好。我试试看。谢谢