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中,路径以斜杠(/)结尾或不结尾,通常表示以下情况:
-
路径以斜杠结尾:这通常表示该路径是一个目录。在Linux中,目录路径通常以斜杠结尾,例如:
/home/user/
表示一个名为 “user” 的目录。 -
路径不以斜杠结尾:这通常表示该路径是一个文件。在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中指定编译的目标文件列表。
注意(小知识点的补充):