我在编译其中一个开源库(libopekele OpenID lib)时遇到了麻烦.
问题是我在需要编译它的系统上没有sudo访问权限.
跑配置.它抱怨缺少htmltidy lib.在非标准路径/ home/geekgod上安装了htmltidy (因为我无法访问/ usr和/ usr/local)
现在的问题是如何使libopekele的配置脚本从/ home/geekgod/include中选择头文件.
进入libopkele的configure.ac脚本,
它正在使用AC_CHECK_HEADERS来搜索tidy.h或者tidy/tidy.h我很确定它是在标准位置寻找这些(/ usr/include)如何将/ home/geekgod添加到标准包含dir
我是一个autotools newb,我很难弄清楚如何轻松地将特定库链接到一个配置的目标.
我有一个源代码包,我想以通常的方式构建:./ configure && make && make install
不幸的是,其中一个cpps缺少对另一个库的引用.手动编译(调整命令行)有效.但我宁愿"修补"编译脚本.编辑链接参考的标准位置在哪里?
undefined reference to `boost::system::get_system_category()
Run Code Online (Sandbox Code Playgroud)
那是我的错误信息btw.
我正在尝试将我的应用程序从手动构建迁移到autoconf,到目前为止它工作得非常好.但我有一个静态库,我无法弄清楚如何集成.该库不会位于通常的库位置 - 二进制文件(.a文件)和头文件(.h文件)的位置将作为configure参数给出.(值得注意的是,即使我将.a文件移动到/ usr/lib或我能想到的任何其他地方,它仍然无法工作.)它也没有传统命名(它不以"lib"或"l"开头) ").
手动编译正在使用这些(目录不可预测 - 这只是一个例子):
gcc ... -I/home/john/mystuff /home/john/mystuff/helper.a
Run Code Online (Sandbox Code Playgroud)
(呃,我实际上不明白为什么直接引用.a文件,而不是-L或者其他任何东西.是的,我对构建C程序有一种半生不熟的理解.)
因此,在我的configure.ac中,我可以使用相关的configure参数使用AC_CHECK_HEADER成功找到标头(.h文件).在AC_CHECK_HEADER中我然后将位置添加到CPFLAGS并且实际C代码中的头文件的#include很好地拾取它.
给定一个已放入$ location的configure参数,并且所需文件的名称是helper.h和helper.a(它们都在同一目录中),到目前为止这是有用的:
AC_CHECK_HEADER([$location/helper.h],
[AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h])
CFLAGS="$CFLAGS -I$location"])
Run Code Online (Sandbox Code Playgroud)
我遇到困难的地方是链接二进制文件(.a文件).无论我尝试什么,我总是得到一个关于该库函数调用的未定义引用的错误.我很确定这是一个链接问题,因为我可以对C代码大惊小怪,并在对该库的函数调用中产生故意错误,该错误会产生早期错误,表明函数原型已经加载并用于编译.
我尝试将包含.a文件的位置添加到LDFLAGS,然后执行AC_CHECK_LIB,但找不到它.
也许我的语法错了,或者我错过了一些更基本的东西,这并不奇怪,因为我是一个新手并且不知道我在做什么.
这是我尝试过的:
AC_CHECK_HEADER([$location/helper.h],
[AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h])
CFLAGS="$CFLAGS -I$location";
LDFLAGS="$LDFLAGS -L$location";
AC_CHECK_LIB(helper)])
Run Code Online (Sandbox Code Playgroud)
没有骰子.AC_CHECK_LIB正在寻找-lhelper我猜(或libhelper?)因此我不确定这是否有问题,所以我也试过了(省略AC_CHECK_LIB并直接在LDFLAGS中包含.a),没有运气:
AC_CHECK_HEADER([$location/helper.h],
[AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h])
CFLAGS="$CFLAGS -I$location";
LDFLAGS="$LDFLAGS -L$location/helper.a"])
Run Code Online (Sandbox Code Playgroud)
为了模拟手动编译,我尝试删除-L但这没有帮助:
AC_CHECK_HEADER([$location/helper.h],
[AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h])
CFLAGS="$CFLAGS -I$location";
LDFLAGS="$LDFLAGS $location/helper.a"])
Run Code Online (Sandbox Code Playgroud)
我尝试了其他组合和排列,但我想我可能会遗漏一些更基本的东西......
================更新
我使用_LDADD在Makefile.am中使用硬编码的.a文件路径,如下所示:
myprog_LDADD=/home/john/mystuff/helper.a
Run Code Online (Sandbox Code Playgroud)
但我无法预测.a文件的位置.出于某种原因,在configure.ac中定义myprog_LDADD不起作用(我希望它可以,所以我可以使用我的动态位置变量),并且没有LDFLAGS,myprog_LDFLAGS,AM_LDFLAGS的更改组合似乎工作.
如果,在Makefile.am中,我尝试使用configure.ac中定义的变量位置,它不起作用
myprog_LDADD=($location)helper.a
Run Code Online (Sandbox Code Playgroud)
================更新
我想我已经明白了,但由于我不知道我在做什么,我真的很感激一些反馈.我使用AC_SUBST()从configure.ac获取myprog_LDADD,因此最终解决方案如下所示:
AC_CHECK_HEADER([$location/helper.h],
[AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h])
CFLAGS="$CFLAGS -I$location"
myprog_LDADD="$location/helper.a"
AC_SUBST(myprog_LDADD)])
Run Code Online (Sandbox Code Playgroud) 似乎有些autoconf项目使用configure.in
文件生成configure
脚本,有些则使用configure.ac
.
使用其中一个或另一个有什么区别/优势?
我有一个数据目录,我想自动生成安装和卸载目标.基本上,我只想将这个目录逐字复制到DATA目录,通常,我可能会单独列出所有文件,如
dist_whatever_DATA=dir/subdir/filea ...
Run Code Online (Sandbox Code Playgroud)
但是当我的目录结构看起来像这样时会出现问题
*root
*subdir
*~10 files
*subdir
*~10 files
*subdir
*~700 files
*subdir
...
~20 subdirs
Run Code Online (Sandbox Code Playgroud)
我只是不能列出作为Makefile.am的一部分包含的所有1000多个文件.那太荒谬了.
我还需要保留目录结构.我应该注意,这些数据根本不是由构建过程生成的,实际上是很短的录音.因此,我不希望automake"检查"我想要安装的每个文件是否已经实际创建,因为它们是否存在,并且无论文件是什么,我知道我希望它安装,等等文件不是,不应该安装.我知道这是其他地方不使用通配符instsalls的理由,但所有可能的原因都不适用于此.
我正在创建一个项目并使用GNU Autoconf工具进行配置和制作.我已经设置了所有的库检查和头文件检查,但似乎无法弄清楚如何检查系统上是否存在可执行文件,如果它不存在则会失败.
我试过了:
AC_CHECK_PROG(TEST,testprogram,testprogram,AC_MSG_ERROR(Cannot find testprogram.))
Run Code Online (Sandbox Code Playgroud)
当configure
它运行并输出时:
Checking for testprogram... find: `testprogram. 15426 5 ': No such file or directory
Run Code Online (Sandbox Code Playgroud)
但不会失败.
我正在开发一个使用autoconf
&的C++项目,automake
我正在努力正确设置包含路径*CPPFLAGS
.我已经阅读了大约3个小时的文件,我还想不通.我不是在寻找黑客,而是寻找正确的方法.这是我的难题.
在我看来,包含路径有3个完全不同的来源:
configure --with-XXX=<PATH>
.#include <file.h>
即使file.h
是包的一部分也使用,所以为了编译它们,我必须正确设置包含路径.(注意,它不是编辑所有这些文件的选项.)CPPFLAGS
.在我目前的设置中:
configure.ac
通过AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>")
.Makefile.am
通过test_CPPFLAGS = -I<path>
.CPPFLAGS
在运行之前设置,则会make
覆盖类型1设置,从而导致编译失败.当然,用户可以尝试使用CXXFLAGS
,但是那个用户有不同的用途(记住,我要求正确的方法来做到这一点,而不是黑客).我尝试通过使用AM_CPPFLAGS
inside 设置Type 1路径来解决这个问题configure.ac
.(供参考:如果您设置AM_CPPFLAGS
而不是CPPFLAGS
,但仍需要运行某些检查AC_CHECK_HEADERS
,则需要临时设置CPPFLAGS
然后还原它以使检查起作用;这将在此处解释.)这样可以释放CPPFLAGS
类型3路径,但不幸的是,编译失败,因为只有没有专门存在的情况下Makefile
才会生成-s .因此,如果存在类型2路径,则编译将失败,因为它不会获得类型1路径.configure
AM_CPPFLAGS
<target>_CPPFLAGS
test_CPPFLAGS
test
修复方法是指定内部Makefile.am
始终使用AM_CPPFLAGS
.但这是"按书"吗?我可以以全局方式执行此操作,还是必须编辑每个单独的target_CPPFLAGS
?还有其他"正确"的解决方案吗?
我正在创建一个libgdata
包含一些测试和未安装程序的库.我遇到的问题是,一旦我安装了一次库,程序似乎就会链接到已安装的版本,而不再是本地版本../src/libgdata.la
.
什么可能导致这个?我做错了什么吗?
这是我的test/Makefile.am
样子:
INCLUDES = -I$(top_srcdir)/src/ -I$(top_srcdir)/test/
# libapiutil contains all of our dependencies!
AM_CXXFLAGS = $(APIUTIL_CFLAGS)
AM_LDFLAGS = $(APIUTIL_LIBS)
LDADD = $(top_builddir)/src/libgdata.la
noinst_PROGRAMS = gdatacalendar gdatayoutube
gdatacalendar_SOURCES = gdatacalendar.cc
gdatayoutube_SOURCES = gdatayoutube.cc
TESTS = check_bare
check_PROGRAMS = $(TESTS)
check_bare_SOURCES = check_bare.cc
Run Code Online (Sandbox Code Playgroud)
(libapiutil
是另一个库,它有一些帮助程序来处理libcurl和libxml ++)
因此,例如,如果我在没有安装任何东西的情况下运行测试,一切正常.我可以在本地进行更改,并立即通过这些程序获取.
如果我安装了这个程序包,这些程序就会编译(看起来它实际上看起来本身就是标题),但是一旦我运行该程序就会抱怨缺少符号.
据我所知,它基于make输出链接到新构建的库(../src/libgdata.la),所以我不确定为什么会发生这种情况.如果我删除已安装的文件,那么对src/*的本地更改就可以了.
我在下面包含了gdatacalendar的make输出.
g++ -DHAVE_CONFIG_H -I. -I.. -I../src/ -I../test/ -I/home/altern8/workspaces/4355/dev-install/include -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -MT gdatacalendar.o -MD -MP -MF .deps/gdatacalendar.Tpo …
Run Code Online (Sandbox Code Playgroud) Autoconf脚本在使用带空格的文件名或路径名时遇到问题.例如,
./configure CPPFLAGS="-I\"/path with space\""
Run Code Online (Sandbox Code Playgroud)
结果(config.log):
configure:3012: gcc -I"/path with space" conftest.c >&5
gcc: with: No such file or directory
gcc: space": No such file or directory
Run Code Online (Sandbox Code Playgroud)
来自./configure的编译命令是ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
,我无法修改它(我也许可以,但以这种方式解决autoconf不是一般解决方案).
我认为它归结为获取一个shell变量,该变量包含要解析为单个命令行变量的空格而不是在空格处分割.我能想到的最简单的shell示例是创建一个带空格的文件,并尝试列出ls
带有shell变量作为参数ls
:
$ touch "a b"
$ file="a b"
$ ls $file
ls: a: No such file or directory
ls: b: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这工作,但是非法,因为在autoconf我无法修改shell代码:
$ ls "$file"
a b
Run Code Online (Sandbox Code Playgroud)
引用事物的下列尝试均无效:
$ file="\"a \"b"; ls $file
ls: "a: No such …
Run Code Online (Sandbox Code Playgroud) 我的程序需要在运行时加载一些文件,这些文件将被安装到任何给定的文件夹中 ./configure --datadir=/somewhere
由于我的程序需要知道此文件夹在运行时的位置,我需要在某处#define一个符号,以便C代码可以作为字符串访问路径.
我目前通过修改编译器标志来做到这一点:
AM_CPPFLAGS = -DDATA_PATH=\"$(pkgdatadir)\"
Run Code Online (Sandbox Code Playgroud)
但是,由于配置脚本已经生成了一个包含其他内容的config.h文件,我希望将符号显示在那里.
那可能吗?