我目前正在将一个小型C项目从autotools转换为CMake.
在旧的configure.in我使用以下行检查每个标头和库函数是否存在:
# Checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h time.h math.h sys/stat.h errno.h unistd.h fcntl.h signal.h])
# Checks for library functions
AC_FUNC_FORK
AC_CHECK_FUNCS([time localtime mktime gmtime exit fork chdir atol signal])
AC_FUNC_STRFTIME
Run Code Online (Sandbox Code Playgroud)
这就是许多autotools项目做AFAIK的事情.
尽管编译器已经检查了必要的头文件并且链接器检查了库函数,但我的代码仍然需要在配置阶段完成这些检查以正确设置它的编译标志#ifdef HAVE_FOOBAR和类似.
在这种情况下,使用CMake检查标头/功能的最佳做法是什么?
我是一个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) 所以几年前我花了一些时间来讨价还价make,这得到了很大的回报.编写用于构建项目和自动执行任务的小makefile非常有趣且富有成效.
当然,缺点是我的makefile非常具体,特别是涉及平台和库位置时.
所以这就是人们告诉我"autotools to rescue!"的地方.当其他人这样做时,他们似乎肯定会做这个伎俩(我喜欢下载东西,跑步configure && make && sudo make install和观看它只是工作),但我无法绕过他们.
我看过一些configure.ac和Makefile.am文件,我只是不明白发生了什么.我不知道标识符的哪一部分是开发人员的选择,哪些部分对autotools有意义.我不确定我是否理解整个流程和重点Makefile.in.我想我只是打了一个从我习惯的系统(make)到达上面一层或两层的精神墙.
任何人都可以指向一个教程或书籍(最好不是一个过于干燥的),可以教我autotools的快乐吗?什么步骤,以及如何使用它们,我怎么能写我自己的configure.ac,并Makefile.am从头开始?告诉我如何有效并与他们玩得开心?
似乎有些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的理由,但所有可能的原因都不适用于此.
我正在开发一个使用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_CPPFLAGSinside 设置Type 1路径来解决这个问题configure.ac.(供参考:如果您设置AM_CPPFLAGS而不是CPPFLAGS,但仍需要运行某些检查AC_CHECK_HEADERS,则需要临时设置CPPFLAGS然后还原它以使检查起作用;这将在此处解释.)这样可以释放CPPFLAGS类型3路径,但不幸的是,编译失败,因为只有没有专门存在的情况下Makefile才会生成-s .因此,如果存在类型2路径,则编译将失败,因为它不会获得类型1路径.configureAM_CPPFLAGS<target>_CPPFLAGStest_CPPFLAGStest
修复方法是指定内部Makefile.am始终使用AM_CPPFLAGS.但这是"按书"吗?我可以以全局方式执行此操作,还是必须编辑每个单独的target_CPPFLAGS?还有其他"正确"的解决方案吗?
如何在 macOS 11(英特尔)上编译 C 项目以在 ?Silicon 上工作?
我当前的构建脚本非常简单:
./configure
make
sudo make install
Run Code Online (Sandbox Code Playgroud)
我已经使用了尝试--host和--target标志有aarch64-apple-darwin和arm-apple-darwin没有任何的运气。
二进制文件始终默认为x86_64:
> file foobar.so
foobar.so: Mach-O 64-bit bundle x86_64
Run Code Online (Sandbox Code Playgroud)
更新:
似乎在--host指定时找不到 cc 和 gcc 。
checking for arm-apple-darwin-cc... no
checking for arm-apple-darwin-gcc... no
Run Code Online (Sandbox Code Playgroud) 如果我编写一个库,并包含用于开发的头文件,并且具有src/Makefile.am如下所示:
AM_CFLAGS = -std=c99 -Wall -Werror -Os
lib_LTLIBRARIES = libmylibrary.la
libmylibrary_la_SOURCES = a.c b.c
include_HEADERS = a.h b.h
Run Code Online (Sandbox Code Playgroud)
一切都很好.然而,a.h和b.h被下直接安装/usr/include(或/usr/local/include).如何安装它们,在我的库特定的子目录中,例如/usr/include/mylibrary?
我有一些由autotools构建的C++项目.
该项目使用了一些我也写的库.库的源代码作为git的子模块导入到项目中.每个库都有自己的autotools文件.
说,我有:
src/<my src files>
modules/libfoo/
libbar/
Makefile.am
Configure.in
<other autotools junk>
Run Code Online (Sandbox Code Playgroud)
我想要的是以某种方式将库包含到主项目编译链中.我想只是包含了Makefile.am的subdir是不够的,因为可以在configure.am中重新进行一些检查.