linux makefile编译so,lib或so库的makefile中不要将编译选项放入gcc命令中

linux下编译的时候,经常会在编译命令中加入一些自定义的编译选项或者参数,比如 gcc -DYF_DEBUG 之类,这样的方式是比较灵活

可以根据需要取消或者加入编译选项,去年搞的那个linux makefile 测试版+发布版 自动切换--"自动化"就是利用这一方法做的;

这一方法对于编译最终可执行文件没任何问题;但对于lib或者so库编译会包含一定的风险,造成一些恶心的麻烦;比如上面说的 YF_DEBUG

用于关闭或者打开一些监控选项,比如一个 struct 定义:

struct yf_conn {

#ifdef YF_DEBUG

yf_int_t cnt;...

#endif

yf_fd_t fd;

};

首先编译成库,如果是采用在编译命令中使用编译参数,当库编译好之后,使用者使用起来会有n多陷阱;如果库编译打开了这一选项,但

使用者不知道这一选项,或者忘记也定义这一选项,那么使用者看到的头文件中的结构定义和库中的结构定义将不一致,然后就是莫名其妙的

内存错误,而且这类错误很难理解,所以比较难fix;

以前碰到过这种恶心的问题,所以对这种问题感觉非常深刻;当时对于这种唯一的解决办法是:库和使用者都记得使用统一的编译选项,只要

一个改了,其他的都统一修改;

随着yifei项目的代码和模块增多增大,lib和so分离的需求也越来越大,于是又一次碰到了同样的问题;回过头来看这一问题,发现其实 autoconfig

提供了其他方法解决这一问题:

之前的定义是:

# debug option

AC_ARG_ENABLE([debug],

[AS_HELP_STRING([--enable-debug], [debug program with log(default is no)])],

[CFLAGS="-DYF_DEBUG -g -O0"],

[CFLAGS="-O2"])

这样多个库以及使用者之间都必须在 configue.in 中都加入这一恶心的重复选项,因为这一选项是加在 gcc 命令之后的;

其实 autoconfig 会自动生成一个头文件,所以完全可以把这个 YF_DEBUG 加入到头文件中去,这样一旦configue --enable-debug 之后,这一选

项就自定加入到了头文件中,而不是只是放在gcc命令中;这样使用者就不需要再重复定义这一选项了;

于是新的方法:

# debug option

AC_ARG_ENABLE([debug],

[AS_HELP_STRING([--enable-debug], [debug program with log(default is no)])],

[CFLAGS="-g -O0";AC_DEFINE([YF_DEBUG], [], ["enable debug"])],

[CFLAGS="-O2"])

btw: autoconfig 和 automake 这一系列工具确定都非常强大,好用;

注意:enable 的 第一个参数比如下面的 syscall 和 --enable-syscall 后面的 enable 的后缀必须完全一致,否则将。。。

开始一不小心将第一个参数写成了 sys_call 害我查了办个小时。。。。

# sys call reptr option

AC_ARG_ENABLE([syscall],

[AS_HELP_STRING([--enable-syscall], [enable sys call])],

[AC_DEFINE([YF_SYS_CALL_REPTR], [], ["enable sys call"])], [])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答你关于在 Linux NDK 交叉编译 SO 的问题。 在交叉编译 SO 之前,你需要先设置交叉编译环境。你可以使用以下命令来设置交叉编译环境: ``` ndk-build APP_ABI=armeabi-v7a NDK_TOOLCHAIN_VERSION=clang ``` 在这个命令,`APP_ABI` 变量用来指定你要交叉编译的 ABI,这里我们选择了 `armeabi-v7a`,你可以根据你的需求选择其他 ABI。`NDK_TOOLCHAIN_VERSION` 变量用来指定你要使用的交叉编译工具链版本,这里我们选择了 `clang`,你也可以选择其他版本。 接下来,你需要编写一个 Makefile 文件来告诉交叉编译器如何编译你的 SO 。下面是一个简单的例子: ``` CROSS_COMPILE = $(NDK_TOOLCHAIN_PREFIX) CC = $(CROSS_COMPILE)gcc CFLAGS = -fPIC -Wall LDFLAGS = -shared LIB_SRC = my_lib.c LIB_OBJ = $(LIB_SRC:.c=.o) LIB_SO = libmy_lib.so all: $(LIB_SO) $(LIB_SO): $(LIB_OBJ) $(CC) $(LDFLAGS) -o $@ $< $(LIB_OBJ): $(LIB_SRC) $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(LIB_SO) $(LIB_OBJ) ``` 在这个例子,我们首先定义了交叉编译器前缀和编译器。在 `all` 目标,我们告诉 Makefile 编译我们的 SO 文件。在 `$(LIB_SO)` 目标,我们使用 `$(LDFLAGS)` 来告诉编译器生成一个共享文件。在 `$(LIB_OBJ)` 目标,我们使用 `$(CFLAGS)` 来告诉编译器生成目标文件。 最后,你需要在 Linux NDK 使用这个 Makefile 文件来交叉编译你的。你可以使用以下命令来交叉编译你的: ``` ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk ``` 在这个命令,`NDK_PROJECT_PATH` 变量用来指定你的项目路径,`APP_BUILD_SCRIPT` 变量用来指定你的 Makefile 文件路径。 当编译完成后,你会在 `libs` 目录下找到你的 SO 文件。你可以将这个 SO 文件复制到你的应用程序,并在代码使用它。 希望这个回答能够帮助到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值