我知道CFLAGS(或CXXFLAGS for C++)是针对编译器的,而CPPFLAGS是由预处理器使用的.
但我仍然不明白其中的区别.
我需要为#include包含的头文件指定一个包含路径 - 因为#include是一个预处理器指令,是我唯一关心的预处理器(CPPFLAGS)吗?
在什么情况下我需要给编译器一个额外的包含路径?
通常,如果预处理器找到并包含所需的头文件,为什么需要告知额外的包含目录?CFLAGS有什么用?
(在我的情况下,我实际上发现这两个允许我编译我的程序,这增加了混乱...我可以使用CFLAGS 或 CPPFLAGS来实现我的目标(至少在autoconf上下文中.)给出了什么?)
我正在尝试将我的应用程序从手动构建迁移到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) 在我的应用程序中,我到目前为止都避免需要加载任何jQuery样式表,但UI-tabs插件似乎需要一些CSS才能工作.好的,很好,但是这些示例可以加载所有UI样式,或许更重要的是,标签样式完全破坏了我自己的外观和感觉.
有没有地方可以学习如何为标签提供足够的CSS工作,所以我可以保留自己的样式?
我不介意最小量的造型有助于很好地安排标签或其他东西,但背景图片,颜色......他们与我自己的造型冲突非常糟糕.
哦,不用了主题滚筒,我相信这对某些人来说很好.只是不在这种情况下,谢谢.
可能是我想念的傻事,但为什么我会收到这个警告?
static void foo(char *path) {
char *bname;
char *path2 = strdup(path);
bname = basename(path2);
Run Code Online (Sandbox Code Playgroud)
(带有basename()调用的行):warning:赋值从整数中生成没有强制转换的指针
实际上,如果我改变这一点,警告就会消失:
bname = (char *)basename(path2);
Run Code Online (Sandbox Code Playgroud)
man 3 basename告诉我:
char *basename(char *path);
Both dirname() and basename() return pointers to null-terminated strings.
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?
据我所知,execve()和family要求其参数数组的第一个参数与其第一个参数也指向的可执行文件相同.就是这样:
execve(prog, args, env);
Run Code Online (Sandbox Code Playgroud)
args [0]通常与prog相同.但我似乎无法找到有关其原因的信息.
我也明白可执行文件(呃,至少是shell脚本)在运行时总是把它们的调用路径作为第一个参数,但是我认为shell会把它放在那里,而execve()只会调用可执行文件使用第一个参数中给出的路径(上面的"prog"),然后在命令行上传递参数数组("args"从上面)....即,我不在命令上调用脚本args列表中的重复可执行路径行....
/bin/ls /bin/ls /home/john
Run Code Online (Sandbox Code Playgroud)
谁能解释一下?
对不起,我不能具体代码,但我看到的问题是异常的.字符串值似乎正在根据其他不相关的代码进行更改.例如,下面传递的参数值只会根据我是否注释掉一个或两个fprintf()调用而改变!通过最后一个fprintf(),该值通常是完全空的(不,我已经检查以确保我没有直接修改参数...我所要做的就是注释掉fprintf()或添加另一个fprintf()并且字符串的值将在某些点发生变化!):
static process_args(char *arg) {
/* debug */
fprintf(stderr, "Function arg is %s\n", arg);
...do a bunch of stuff including call another function that uses alloc()...
/* debug */
fprintf(stderr, "Function arg is now %s\n", arg);
}
int main(int argc, char *argv[]) {
char *my_arg;
... do a bunch of stuff ...
/* just to show you it's nothing to do with the argv array */
my_string = strdup(argv[1]);
/* debug */
fprintf(stderr, "Argument 1 is %s\n", my_string);
process_args(my_string);
} …Run Code Online (Sandbox Code Playgroud)