我需要链接另一个程序生成的目标文件,并且
在其文件夹中找到
您所描述的是一个非常不寻常的要求,而不是那些 Autotools 旨在干净或轻松处理的要求。特别是,与库相比,Autoconf 没有专门适用于搜索裸对象文件的机制,并且 Automake 在链接时没有特别自动化包含此类对象。尽管如此,这些工具确实有足够的通用功能来做你想做的事。它不会像你想的那样整洁。
我认为如果我对路径进行硬编码并将
name-of-obj.o 前面的 package_LDADD 变量应该可以工作,但是
情况是我不想那样做。
我认为这是您要避免的“硬编码路径”部分。将项目添加到适当的LDADD 变量是不可协商的;这是让您的对象包含在链接中的正确方法。
如果找不到对象,我希望配置失败并告诉
name-of-obj.o 丢失的用户。
那么,关键似乎是让configure 执行对您的目标文件的搜索。 Autoconf 没有内置的机制来执行这样的搜索,但它只是一个基于宏的 shell-script 生成器,所以你可以在 shell script + Autoconf 中编写这样的搜索,可能是这样的:
AC_MSG_CHECKING([for name-of-obj.o])
OTHER_LOCATION=
for my_dir in
/some/location/other_program/src
/another/location/other_program.12345/src
$srcdir/../relative/location/other_program/src; do
AS_IF([test -r "${my_dir}/name-of-obj.o"], [
# optionally, perform any desired test to check that the object is usable
# ... perhaps one using AC_LINK_IFELSE ...
# if it passes, then
OTHER_LOCATION=${my_dir}
break
])
done
# Check whether the object was in fact discovered, and act appropriately
AS_IF([test "x${OTHER_LOCATION}" = x], [
# Not found
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Cannot configure without name-of-obj.o])
], [
AC_MSG_RESULT([${OTHER_LOCATION}/name-of-obj.o])
AC_SUBST([OTHER_LOCATION])
])
这是功能性的,但您当然可以进行修饰,例如让包生成器通过命令行参数 (AC_ARG_WITH(...)) 指定要使用的位置。如果您想对多个对象执行此操作,那么您可能希望至少将其中的一部分封装到自定义宏中。
Automake 方面的参与要少得多。要获取链接的对象,只需将其添加到相应的LDADD 变量中,使用上面创建的输出变量,例如:
foo_LDADD = $(OTHER_LOCATION)/name-of-obj.o
请注意,如果您只构建一个程序目标,则可以使用通用的LDADD 而不是foo_LDADD,但请注意,默认情况下,这些是替代而不是补充。
话虽如此,总体而言这是一个坏主意。如果你想链接不属于你的项目的东西,那么你应该从已安装的库中获取它。当然,这可以是一个本地的、定制的库,只要它是一个库,而不是一个裸目标文件,并且它已安装。如果您不想依赖或分发单独的共享库,它可以是静态库。
另一方面,如果您的项目是较大构建的一部分,那么最好的方法可能是将其集成到该构建中,也许作为子项目。最好还是链接一个库而不是一个裸对象文件,但在子项目上下文中,使用未安装到构建系统的库可能是有意义的。与告诉它在哪里可以找到所需库的命令行参数结合使用,这可以使所需的 Autoconf 代码更加简洁明了。