前言
-
在使用 cmake 交叉编译应该应用程序时,好像没有手动设置【链接脚本】,也能正常构建生成 Makefile,并且可以正常 Make 生成需要的 应用程序。
-
但是有些应用程序,需要手动指定【链接脚本】,比如修改链接地址,这在 cmake 构建中如何操作呢?
-
当前没有设置链接脚本,发现编译后的应用程序的入口地址为 0
如下: Entry point address: 0x0
readelf -h routingmanagerd
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: AArch64
Version: 0x1
Entry point address: 0x0
Start of program headers: 64 (bytes into file)
Start of section headers: 226912 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 8
Size of section headers: 64 (bytes)
Number of section headers: 38
Section header string table index: 37
了解 cmake
-
默认 cmake 的构建操作只生成 Makefile,然后需要再执行 make 命令进行编译、链接。
-
所以可以在 cmake 的构建文件中,增加【链接脚本】的选项
cmake 设置链接脚本路径
- cmake 可以通过
set
命令轻松设置 环境变量,这里的操作是,在 cmake 文件中增加
set(LINK_SCRIPTS "-T/home/zhangsz/smart/adas/software/userapps/linker_scripts/aarch64/link.so.lds")
-
说明:可以使用 set 在 cmake 中设置环境变量,环境变量名字可以自定义。如果环境变量存在,可以使用
${LINK_SCRIPTS}
获取设置过的环境变量 -
这里的操作是:设置环境变量
${LINK_SCRIPTS}
为 指定的链接脚本的路径 -
-T/home/zhangsz/userapps/linker_scripts/aarch64/link.so.lds
这里的-T
表示指定链接脚本,用于 gcc 的编译参数, 后面是 链接脚本的路径
cmake 应用程序生成
-
cmake 生成目标文件,默认使用:
target_link_libraries
,这里是动态链接,如下: -
在
target_link_libraries(routingmanagerd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${DL_LIBRARY} ${DLT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${LINK_SCRIPTS})
中增加了刚才加入链接脚本的【环境变量】,这里是${LINK_SCRIPTS}
- cmake 最终会把这些操作,环境变量,转换为 gcc 或者交叉编译 gcc 的 参数
编译验证
- 编译的详细 LOG,发现 链接脚本设置成功了
-
cmake 后,再使用 make 进行编译,发现编译的应用程序,链接地址与指定的链接脚本的地址一致,说明 指定链接脚本的操作 设置成功了
-
入口函数地址
Entry point address: 0x201000
,链接脚本指定的地址
readelf -h routingmanagerd
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: AArch64
Version: 0x1
Entry point address: 0x201000
Start of program headers: 64 (bytes into file)
Start of section headers: 232208 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 5
Size of section headers: 64 (bytes)
Number of section headers: 32
Section header string table index: 31
如何查看详细的编译过程
-
cmake 配置文件中设置:
set(CMAKE_VERBOSE_MAKEFILE ON)
-
make V=1
或者VERBOSE=on
可以让编译的细节更多 -
make 编译时可以把串口的打印重定向到一个文件,这样查看这个编译信息文件,可能更方便
make VERBOSE=on 2>&1 | tee output_log.txt
小结
-
由于平时使用 cmake 不多,大部分情况下可以手动编写 Makefile,然后使用 make 编译,不过 cmake 的使用,应该会然 构建编译更简单
-
初步了解了 在 cmake 中设置与读取【环境变量】的操作,用于在 gcc 编译参数中增加 设置链接脚本