为avr构建代码时出现cmake构建问题
Posted
技术标签:
【中文标题】为avr构建代码时出现cmake构建问题【英文标题】:cmake build problem when building code for avr 【发布时间】:2019-03-17 19:48:43 【问题描述】:我正在尝试为 avr atmega328p 构建一个示例项目。我面临一个奇怪的问题。我有以下目录结构。
inc/core/device_support.h
src/main.c
src/core/device_support.c
我有两个项目设置,一个使用 make,另一个使用 cmake。当我使用 make 构建时,一切正常。但是当我使用 cmake 时,它无法编译。 (如果我运行 avr-size -A myProject.elf
并且它在目标 mcu 上运行不正确,.text 部分就不一样了)。但是,如果我在 cmake 项目目录中手动运行编译命令,并将构建目录作为工作目录,一切正常。
我已将问题缩小到这样一个事实,即如果我们从核心 /home/user/avr/build/core
运行编译命令它不起作用,并且如果我在 /home/user/avr/build
构建目录中运行命令它工作正常。我不知道为什么会发生这种情况。
我的问题是为什么在不同的目录中会导致编译混乱以及如何在 cmake 中修复它。
用 make 我有类似的东西:
avr-gcc -DARDUINO=10808 -DF_CPU=160000000L -I/home/user/avr/inc/core -mmcu=atmega328p -ffunction-sections -fdata-sections -MMD -flto -std=gnu11 -fno-fat-lto-objects -Os -w -g -MD -MT /home/user/avr/src/core/device_support.c -o /home/user/avr/build/core/device_support.o
并且我有 cmake 自动生成的脚本:
cd /home/user/avr/build/core && avr-gcc -DARDUINO=10808 -DF_CPU=160000000L -I/home/user/avr/inc/core -mmcu=atmega328p -ffunction-sections -fdata-sections -MMD -flto -std=gnu11 -fno-fat-lto-objects -Os -w -g -MD -MT -o src/CMakeFiles/core.dir/src/core/device_support.o /home/user/avr/src/core/device_support.c
更新 01:
avr-size -A myProject.elf 输出(cmake):
section size addr
.data 0 8388864
.text 740 0
.bss 9 8388864
.comment 17 0
.note.gnu.avr.deviceinfo 64 0
.debug_aranges 120 0
.debug_info 3537 0
.debug_abbrev 1965 0
.debug_line 1044 0
.debug_frame 124 0
.debug_str 1175 0
.debug_loc 843 0
.debug_ranges 40 0
Total 9678
avr-size -A myProject.elf 输出(制作):
section size addr
.data 0 8388864
.text 930 0
.bss 9 8388864
.comment 17 0
.note.gnu.avr.deviceinfo 64 0
.debug_aranges 104 0
.debug_info 3559 0
.debug_abbrev 2002 0
.debug_line 1134 0
.debug_frame 180 0
.debug_str 1139 0
.debug_loc 1154 0
.debug_ranges 24 0
Total 10316
您可以在 .text 部分看到不同之处。它是一个简单的 LED 闪烁代码当我在 cmake 情况下在设备上运行它时,LED 有时会保持亮起,而在其他情况下会完全熄灭。如果我通过从 cmake 的输出运行相同的命令手动编译相同的代码,但将构建目录作为我的工作目录,那么 LED 会按预期闪烁。
在任何一种情况下,构建期间都没有错误。唯一的区别是在构建目录中。如果我手动构建并且我的工作目录没有构建,那么在这种情况下它也会失败。由于某种原因,在编译期间位于 build 目录中很重要,我不知道为什么。
更新 02: 示例代码已上传至:https://github.com/systemangle/mcve_avr
请参阅项目自述文件。
【问题讨论】:
“它不能在目标 mcu 上正确运行” - 详细说明。您在项目构建期间是否有任何警告或错误?当你尝试运行创建的精灵时会打印什么? 您只发布了编译命令device_support.o
。也许问题出在链接器命令行中?你能发布来自 cmake 和 make 的所有消息吗?
@KamilCuk 链接器命令在我手动运行时运行良好,只需从输出中复制它即可。我将使用所有命令更新问题。但是正如我所说,如果我使用 cmake,每个编译的目标文件的大小都是不同的,如果我通过简单地从输出中复制命令手动编译,相同的代码文件会产生正确的目标文件大小,唯一重要的是我必须在构建目录中,而编译。
然后让我们检查对象.o
文件。尝试创建一个最小的.c
文件,其差异是可观察的,发布它,发布生成的程序集输出。在main.o
或device_support.o
或两者中是否可以观察到差异? cmake
或 make
是否与问题相关?你能创建一个 MCVE,一个复制问题的小脚本吗?将cat <<EOF >file.c ....
文件内容和avr-gcc ....
cd .... && avr-gcc ..
编译命令和avr-size
的输出也包含在一个脚本中会很棒。这个问题很奇怪。可以发avr-gcc
版本吗?
@KamilCuk 是的,所有 .o 文件都使用 cmake 不同。我会尝试制作 MCVE。 make 和 cmake 的相关性是这样的,因此我正在尝试将基于 make 的项目移植到 cmake。我所做的是将 Makefile 替换为 CMakeLists.txt 并为 cmake 创建工具链以选择合适的编译器等。我尝试使用 gcc 8.3.0 和 arduino gcc 5.4.0。事实上,对于 MCVE,我正在尝试将 arduino 文件移植到我的 cmake 项目设置中。到目前为止,我看到了类似的结果。完成后我会分享。
【参考方案1】:
由于某种原因,在编译期间位于 build 目录中很重要,我不知道为什么
那么您可能已经有了答案。这个问题似乎与 CMake 无关。 也许您可以尝试使用 cmake 进行源内构建,看看会发生什么。 否则,如果你想模仿手写的 Makefile 行为,你可以避免使用任何 add_subdirectory,而只在项目的根目录下写一个大的 CMakeLists.txt。
话虽如此,如果编译输出因调用编译器时的位置而异,那么我认为你最好向提供交叉编译器的人员询问有关这种奇怪行为的问题.
您是否尝试过在不同目录中手动编译文件? 这会改变输出的目标文件吗?
【讨论】:
以上是关于为avr构建代码时出现cmake构建问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 Cmake 文件在 Visual Studio 中构建 Qt 项目时出现链接错误