Linux中Makefile

CC := gcc  //表示设置一个名为CC的变量,值为gcc
AR := ar   //定义一个AR变量,后边可以用AR表示ar

BLD_CFLAGS := $(CFLAGS) -Wall -Werror 
BLD_CFLAGS += -Os -fPIC

        这行代码的作用是将 `-Os` 和 `-fPIC` 这两个编译选项追加到 `BLD_CFLAGS` 变量的值后面。`+=` 是追加操作符,用于将新的选项添加到变量的现有值之后。

`-Os` 表示使用优化级别为最小尺寸(Optimize for Size),这会让编译器优化生成的代码以减小最终可执行文件的大小。

`-fPIC` 表示生成位置独立的代码(Position Independent Code),这在生成动态链接库时非常有用,因为它使得代码可以在内存中的任何位置加载,而不依赖于特定的内存地址。

        所以,这行代码的目的是将 `-Os` 和 `-fPIC` 这两个编译选项添加到 `BLD_CFLAGS` 中,以便在构建过程中使用这些选项。


TOP_DIR := $(shell pwd)

        在这个代码片段中,TOP_DIR 是一个变量,它的值等于 $(shell pwd)$(shell ...) 语法用于在 Makefile 中执行命令,并将其输出作为变量的值。

pwd 是一个用于获取当前工作目录的命令。通过使用 $(shell pwd),可以获取当前工作目录的路径,并将其赋值给 TOP_DIR 变量。

        这行代码的作用是将当前工作目录的路径赋给 TOP_DIR,以便在后续的代码中可以使用 TOP_DIR 变量来引用当前工作目录的路径。

$(info $(TOP_DIR))     【$(info hello)】

        $(info $(TOP_DIR)) 是一个 make 函数和指令的组合,用于在 makefile 执行过程中打印出变量 TOP_DIR 的值。$(info ...) 是一个 make 函数,用于在 makefile 执行过程中打印消息到标准输出。传入 $(TOP_DIR) 作为参数,将打印出 TOP_DIR 变量的值。因此,当执行 $(info $(TOP_DIR)) 时,它将在 makefile 执行期间打印出 TOP_DIR 变量的值。

# 路径定义
TOP_DIR := $(shell pwd)
DEMOS_DIR := demos                        //用DEMOS_DIR表示demos
OUT_DIR := output                               //用OUT_DIR 表示output
LIB_DIR := output/lib                            //用LIB_DIR 表示output/lib
INCLUDE_DIR := output/include          //用INCLUDE_DIR 表示output/include
NOPOLL_DIR := external/nopoll/         //用NOPOLL_DIR 表示external/nopoll/ 

小知识点补充:

在Linux中,路径以斜杠(/)结尾或不结尾,通常表示以下情况:

  1. 路径以斜杠结尾:这通常表示该路径是一个目录。在Linux中,目录路径通常以斜杠结尾,例如:/home/user/ 表示一个名为 “user” 的目录。

  2. 路径不以斜杠结尾:这通常表示该路径是一个文件。在Linux中,文件路径通常不以斜杠结尾,例如:/home/user/file.txt 表示一个名为 “file.txt” 的文件。

需要注意的是,在某些情况下,路径结尾的斜杠可能是可选的,具体取决于文件系统的实现。大多数Linux系统会自动忽略结尾斜杠的存在或缺失,因此 /home/user 和 /home/user/ 通常被认为是相同的路径。

总而言之,斜杠结尾的路径表示目录,不结尾的路径表示文件,而对于绝大多数Linux系统来说,斜杠的存在与否在路径的使用上没有重大影响。

# 设置默认链接路径为$(LIB_DIR)
LIB_LDFLAGS := -L $(LIB_DIR) -Wl,-rpath,$(LIB_DIR)

        这段代码用于设置默认的链接路径(LIB_LDFLAGS),将其指定为 $(LIB_DIR) 变量的值。同时,通过 -Wl,-rpath,$(LIB_DIR) 选项告诉链接器在运行时添加 $(LIB_DIR) 目录作为运行时路径(runtime path)。

其中:

  • -L $(LIB_DIR) 用于指定在链接时要搜索的库文件路径。-L 选项后面跟着的是库文件的目录路径 $(LIB_DIR)

  • -Wl 是告诉编译器将后面的选项传递给链接器(ld)。-Wl,-rpath,$(LIB_DIR) 选项将 $(LIB_DIR) 目录添加到生成的可执行文件的运行时路径中。

通过设置这些链接路径,可以确保在链接程序时能够正确找到和加载所需的库文件。这对于依赖于特定库文件的程序是非常重要的,可以让程序在运行时能够找到它们并正常工作。

        -Wl,-rpath,$(LIB_DIR) 是一个传递给链接器(ld)的选项,用于指定程序运行时的动态库搜索路径。下面对该选项的各部分进行解释:

  • -Wl: 这是一个编译器(gcc)的选项,用于将后续的选项传递给链接器。-Wl 可以用于将特定的选项传递给链接器而不处理其他编译器选项。

  • -rpath: 这是链接器的选项,用于指定运行时加载动态库时的搜索路径。通过使用 -rpath 选项,可以将指定的目录添加到可执行文件的运行时路径中,以供动态链接器在程序运行时寻找动态库文件。

  • $(LIB_DIR): 这是一个变量,表示库文件的目录路径。在Makefile中,$(LIB_DIR) 可以是预定义的或自定义的变量,用于指定库文件的路径。

使用 -Wl,-rpath,$(LIB_DIR) 可以让链接器在程序运行时动态链接库时,在指定的 $(LIB_DIR) 目录中搜索所需的动态库文件。这样可以确保程序能够正确加载所需的库文件,而无需在运行时手动设置 LD_LIBRARY_PATH 环境变量或在程序中显式指定库文件路径。

总之,-Wl,-rpath,$(LIB_DIR) 选项用于设置程序运行时的动态库搜索路径,确保程序能够正确加载所需的动态库文件。

AA := $(shell echo false)
$(info $(AA)) 

        利用echo也是一条命令行

ra_exist = $(shell if [ -d $(NOPOLL_DIR) ]; then echo "true"; else echo "false"; fi)

        这段代码通过在Makefile中使用 `$(shell ...)` 语法来执行shell命令,并将命令的结果赋值给变量 `ra_exist`。具体来说,该命令在shell中执行了以下操作:
                                        if [ -d $(NOPOLL_DIR) ]; then
                                                    echo "true"
                                        else
                                                    echo "false"
                                        fi

        其中 `$(NOPOLL_DIR)` 是一个变量,表示目录路径。该命令首先检查 `$(NOPOLL_DIR)` 变量所表示的目录是否存在。如果该目录存在,则输出 "true",否则输出 "false"。

执行该shell命令后,`$(shell ...)` 将命令输出(true或false)赋值给 `ra_exist` 变量。这样,可以在Makefile中根据 `ra_exist` 变量的值判断目录是否存在,并根据需要执行其他操作。

注意,`$(shell ...)` 语法在Makefile中允许执行shell命令并获取结果作为变量的一部分。这使得可以在构建过程中根据需要进行动态的判断和操作。

        具体来说,-d 是用于测试文件类型的一个选项,它跟随在[ ](方括号)内的文件路径之后。-d 会判断给定的文件路径是否是一个目录。如果路径存在并且是一个目录,测试结果为真(true);否则,测试结果为假(false)。

在这个上下文中,-d 的用途是检查变量 $(NOPOLL_DIR) 所表示的目录是否存在。如果该目录存在,则执行 then 后面的命令 echo "true" 输出 “true”;否则,执行 else 后面的命令 echo "false" 输出 “false”。

这样,通过将 ra_exist 定义为 $(shell if [ -d $(NOPOLL_DIR) ]; then echo "true"; else echo "false"; fi),可以通过执行shell命令在Makefile中动态地将变量设置为目录是否存在的布尔值。

ifeq ("$(ra_exist)", "true")
NOPOLL_SRC := $(shell find $(NOPOLL_DIR) -name "*.c")
NOPOLL_FILES := $(NOPOLL_SRC:.c=.o)
NOPOLL_FILES := $(addprefix $(OUT_DIR)/,$(NOPOLL_FILES))
NOPOLL_LIB := libnopoll
LIB_LDFLAGS += -lnopoll
STA_LIB_LDFLAGS += $(LIB_DIR)/libnopoll.a 
endif

        这段Makefile代码使用了 find 命令和变量扩展来查找指定目录中的所有以 “.c” 结尾的C语言源代码文件。具体来说,find 命令用于在指定的目录中递归查找文件。在这里,$(NOPOLL_DIR) 是一个变量,表示目录路径,它会被展开为真实的目录路径。

-name "*.c" 是用于指定要查找的文件名模式。在本例中,它表示查找以 “.c” 结尾的文件。

$(shell ...) 语法用于在Makefile中执行shell命令,并将其输出作为变量的值。所以,整个 $(shell ...) 命令的作用是运行 find 命令来获取符合条件的文件列表。

最后,将找到的符合条件的文件列表赋值给了变量 NOPOLL_SRC

通过这样的方式,可以根据指定目录中的C语言源文件生成文件列表,以便在Makefile编译规则中使用。

        这部分的代码将 NOPOLL_SRC 变量中的每个源文件路径的扩展名 .c 替换为 .o。它使用了Makefile中的变量扩展和模式替换功能。

具体来说,$(NOPOLL_SRC:.c=.o) 表示对 NOPOLL_SRC 变量中的每个元素(源文件路径)进行扩展和替换。:.c=.o 指定了将扩展名 .c 替换为 .o 的替换规则。

例如,如果 NOPOLL_SRC 的值为 src/file1.c src/file2.c src/file3.c,那么 $(NOPOLL_SRC:.c=.o) 将被扩展为 src/file1.o src/file2.o src/file3.o。它将 .c 扩展名的源文件路径替换为相应的 .o 目标文件路径。

这样,变量 NOPOLL_FILES 将包含从 NOPOLL_SRC 变量中生成的所有目标文件路径,用于在Makefile中指定编译的目标文件列表。

注意(小知识点的补充):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值