Makefile中的条件链接

时间:2014-12-24 23:43:01

标签: makefile linker conditional

在我的Makefile中,我只想在机器上安装它时才链接到库。因此,例如,如果库是hwloc,我想执行以下操作:

xfoo : foo.o
   if (hwloc installed)
      gcc foo.o -o $@ -lhwloc
   else
      gcc foo.o -o $@

无论如何都要做这样的事情?即是否可以检查是否安装了特定库并将其用作Makefile中的条件?

3 个答案:

答案 0 :(得分:1)

这是错误的答案:

xfoo : foo.o
   if (hwloc installed); then gcc foo.o -o $@ -lhwloc; else gcc foo.o -o $@; fi

从Makefile执行的命令不必只是简单的单个命令。 shell可以执行的任何操作都可以从Makefile中调用。包括整个脚本,夹在一行。

这是正确答案:

但是,上述方法是错误的。您会发现许多免费软件包始终会执行此类操作:有条件地链接到库中,如果可用的话。

但它的完成方式是在运行make之前运行单独的configure脚本。将源代码tarball抓取到您选择的随机免费软件包中,然后阅读安装说明。在运行configure之前,他们都会告诉您先运行make脚本。

绝大多数免费软件包使用GNU工具链来创建他们的构建系统 - configure脚本和Makefile。 GNU工具链由autoconfautomake工具组成(在许多情况下也是libtool)。有关更多信息,请访问Google。

还有一些其他不太受欢迎的工具链,但GNU工具链是最常用的工具链,对于这种情况。因此,要按照您要做的事情做一些事情,通常这样做的方式是:

configure.ac文件中:

AC_CHECK_LIB(hwloc,some_function_in_the_hwloc_library,[LINK_HWLOC=-lhwloc])
AC_SUBST(LINK_HWLOC)

Makefile.am文件中:

hwloc_LDADD=@LINK_HWLOC@

就是这样。这就是大多数自由软件包需要完成同样事情的无数次。 autoconfautomake将负责编写实现此目的的shell脚本和makefile。

答案 1 :(得分:1)

我目前无法访问Linux机器,所以请原谅我的答案是未经测试的。

我将恭敬地不同意我的两位前任。

首先,使用autotools修改现有的Makefile是一个坏主意。 Autotools是为了避免担心在简单的用例中创建一个好的Makefile。这就好像OP在我的Python脚本中询问“如何将+更改为-”,答案是“编写一个shell脚本来修改脚本,将其保存在临时文件中并执行文件”< / p>

第二个答案,为什么可以自动无痛地手动完成某些事情?

所以,恕我直言,正确的答案是,这是$(wildcard)的确切用例:

xfoo: foo.o $(wildcard libhwloc.a) 
    gcc $(patsubst lib%.a, -l%, $^) -o $@

注意:库已提前安装或未安装,但在构建期间

答案 2 :(得分:0)

如果您不想参与autotools / etc。对于这个(虽然合理的解决方案也是合理的,想要避免这么简单的事情)并且你不想玩猜猜游戏关于人们可能或可能没有安装这个hwloc库的地方那么你能做的最好的事情就是让人们手动启动这项功能。

使用三个(或四个)make变量。 USE_HWLOCHWLOC_LDLIBSHWLOC_CFLAGS以及可能HWLOC_LDFLAGS

然后,当定义USE_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)