【问题标题】:cmake for embedded: remove Linux POSIX headers嵌入式 cmake:删除 Linux POSIX 标头
【发布时间】:2019-04-26 22:42:38
【问题描述】:

所以,我正在为 RIOT OS 开发一个嵌入式库。由于我的库使用 Cmake,但 RIOT 使用简单的 Makefile,我只编译一个静态库,然后在编译时将其链接到 RIOT。所以我编译库:我将所有包含文件传递给 CMAKE_C_FLAGS 这是必需的,因为我的库使用 pthreads 并且 RIOT 支持它。

-DCMAKE_C_FLAGS="-I/home/citrullin/git/riot_libs/core/include -I/home/citrullin/git/riot_libs/drivers/include -I/home/citrullin/git/riot_libs/sys/include -I/home/citrullin/git/riot_libs/boards/native/include -DNATIVE_INCLUDES -I/home/citrullin/git/riot_libs/boards/native/include/ -I/home/citrullin/git/riot_libs/core/include/ -I/home/citrullin/git/riot_libs/drivers/include/ -I/home/citrullin/git/riot_libs/cpu/native/include -I/home/citrullin/git/riot_libs/sys/include -I/home/citrullin/git/riot_libs/cpu/native/include -I/home/citrullin/git/riot_libs/examples/iota_transaction_node/bin/pkg/native/iota-wallet/src -I/home/citrullin/git/riot_libs/sys/posix/include -I/home/citrullin/git/riot_libs/sys/posix/pthread/include" .

所以效果很好。但不知何故,cmake 也试图包含 posix 的 linux 头文件。由于这是嵌入的,它不应该那样做。

Scanning dependencies of target iota_wallet
[ 11%] Building C object CMakeFiles/iota_wallet.dir/src/iota/addresses.c.obj
In file included from /usr/arm-none-eabi/include/sys/types.h:239:0,
                 from /usr/arm-none-eabi/include/stdio.h:61,
                 from /home/citrullin/git/riot_libs/examples/iota_transaction_node/bin/pkg/bluepill/iota-wallet/src/iota/common.h:4,
                 from /home/citrullin/git/riot_libs/examples/iota_transaction_node/bin/pkg/bluepill/iota-wallet/src/iota/addresses.c:2:
/usr/arm-none-eabi/include/sys/_pthreadtypes.h:154:20: note: previous declaration of 'pthread_mutex_t' was here
 typedef __uint32_t pthread_mutex_t;      /* identify a mutex */

那么,我的问题是:如何告诉 cmake 不包含 linux 头文件?

这是current CMakeList.txt I use.

/e 我对 Makefile 进行了同样的尝试。同样的问题出现在这里。

make -e CFLAGS="-isystem /usr/arm-none-eabi/include/newlib-nano -I/home/citrullin/git/riot_libs/core/include -I/home/citrullin/git/riot_libs/drivers/include -I/home/citrullin/git/riot_libs/sys/include -I/home/citrullin/git/riot_libs/boards/bluepill/include -I/home/citrullin/git/riot_libs/boards/common/stm32f103c8/include -I/home/citrullin/git/riot_libs/cpu/stm32f1/include -I/home/citrullin/git/riot_libs/cpu/stm32_common/include -I/home/citrullin/git/riot_libs/cpu/cortexm_common/include -I/home/citrullin/git/riot_libs/cpu/cortexm_common/include/vendor -I/home/citrullin/git/riot_libs/sys/libc/include -I/home/citrullin/git/riot_libs/examples/iota_transaction_node/bin/pkg/bluepill/iota-wallet/src -I/home/citrullin/git/riot_libs/sys/posix/include -I/home/citrullin/git/riot_libs/sys/posix/pthread/include" lib
arm-none-eabi-gcc -c -o build/addresses.o src/iota/addresses.c -isystem /usr/arm-none-eabi/include/newlib-nano -I/home/citrullin/git/riot_libs/core/include -I/home/citrullin/git/riot_libs/drivers/include -I/home/citrullin/git/riot_libs/sys/include -I/home/citrullin/git/riot_libs/boards/bluepill/include -I/home/citrullin/git/riot_libs/boards/common/stm32f103c8/include -I/home/citrullin/git/riot_libs/cpu/stm32f1/include -I/home/citrullin/git/riot_libs/cpu/stm32_common/include -I/home/citrullin/git/riot_libs/cpu/cortexm_common/include -I/home/citrullin/git/riot_libs/cpu/cortexm_common/include/vendor -I/home/citrullin/git/riot_libs/sys/libc/include -I/home/citrullin/git/riot_libs/examples/iota_transaction_node/bin/pkg/bluepill/iota-wallet/src -I/home/citrullin/git/riot_libs/sys/posix/include -I/home/citrullin/git/riot_libs/sys/posix/pthread/include
In file included from /home/citrullin/git/riot_libs/sys/posix/pthread/include/pthread.h:38:0,
                 from src/iota/conversion.h:13,
                 from src/iota/addresses.c:8:
/home/citrullin/git/riot_libs/sys/posix/pthread/include/pthread_threading_attr.h:34:3: error: conflicting types for 'pthread_attr_t'
 } pthread_attr_t;
   ^~~~~~~~~~~~~~
In file included from /usr/arm-none-eabi/include/sys/types.h:239:0,
                 from /usr/arm-none-eabi/include/stdio.h:61,
                 from src/iota/addresses.c:2:
/usr/arm-none-eabi/include/sys/_pthreadtypes.h:75:3: note: previous declaration of 'pthread_attr_t' was here
 } pthread_attr_t;
   ^~~~~~~~~~~~~~
In file included from /home/citrullin/git/riot_libs/sys/posix/pthread/include/pthread.h:38:0,
                 from src/iota/conversion.h:13,
                 from src/iota/addresses.c:8:
/home/citrullin/git/riot_libs/sys/posix/pthread/include/pthread_threading_attr.h:39:8: error: redefinition of 'struct sched_param'
 struct sched_param {
        ^~~~~~~~~~~
In file included from /usr/arm-none-eabi/include/sys/_pthreadtypes.h:23:0,
                 from /usr/arm-none-eabi/include/sys/types.h:239,
                 from /usr/arm-none-eabi/include/stdio.h:61,
                 from src/iota/addresses.c:2:
/usr/arm-none-eabi/include/sys/sched.h:48:8: note: originally defined here
 struct sched_param {
        ^~~~~~~~~~~

这些重复定义错误更多。看起来它们的性质都是一样的。

重现步骤:

  1. 克隆此repository(分支:iota_new_implementation)

  2. cd 到文件夹 examples/iota_transaction_node

  3. 执行 make

带有 Makefile 的版本。提交:7e1d8884ab135ae64cee02c8c1a447015f4325bc

带有 CMake 的版本。提交:dbf32e727889afa3efb466cfdc8561e697af48b0

USEPKG += iota-wallet

在示例的 Makefile 中指的是this packageThis Makefile 用于制作静态库。

Cmake 日志:

CmakeError.log

CMakeOutput.log

Console Output

生成文件:

Console Output

【问题讨论】:

  • 我不确定你是否可以在包含 stdlib.h... 时避免这样做?
  • @Silmathoron 我在 RIOT 中把它改成了 native,所以使用 arm-none-eabi 编译器。我改变了问题。令人困惑的部分是 arm-none-eabi 包含 pthread 的头文件。这不应该存在,因为 arm-none-eabi 不针对任何供应商或操作系统。 pthreads 是操作系统特定的东西。
  • 我对此感到有点惊讶......也许这是一个错误(怀疑)但也许你没有告诉编译器你认为你是什么。你能发布 cmake 配置日志吗?
  • 我认为设置 -I 不足以进行交叉编译。见cmake.org/cmake/help/latest/manual/…。我注意到 RIOT OS 有这个用于生成工具链文件的帮助脚本。 github.com/RIOT-OS/RIOT/blob/master/dist/tools/cmake/…
  • @Fred 我链接了 repo,所以你可以复制它。我不确定,但我想我已经使用了工具链生成器。我可以用 Makefile 重现同样的问题。您可以在此处 (github.com/Citrullin/RIOT/commit/…) 看到 Makefile 在使用 cmake 之前的样子。

标签: makefile cmake gnu-make riot-os


【解决方案1】:

问题不在于使用 POSIX 标头嵌入的 CMake。 这是对错误的误解。

我认为混淆来自Scanning dependencies of target iota_wallet[ 11%] Building C object CMakeFiles/iota_wallet.dir/src/iota/addresses.c.obj。这是两个不同的步骤,它们都不涉及 CMake。 CMake 没有扫描任何东西。当 CMake 生成 Makefiles 时,它只是将 CMakeLists.txt 添加为构建依赖项的一部分。如此更新 CMakeLists.txt 将在运行 make 时重新生成新的 Makefile。当它这样做时,它会打印Scanning dependencies...

实际问题出现在使用arm-none-eabi 编译源代码。 该编译器附带 newlib 作为其 c 库。无论出于何种原因,newlib 包含一些 pthread 的头文件。每当您在源代码中包含像stdint.hstdlib.h 这样的头文件时,它都会包含sys/types.h,然后再包含sys/_pthreadtypes.h。这与 RIOT 附带的 pthreads 头文件冲突。

您可以通过使用-std=c99 编译来解决此问题。

或者您可以通过编辑文件 /usr/arm-none-eabi/include/sys/_pthreadtypes.h 来解决此问题。

变化:

#if defined(_POSIX_THREADS) || __POSIX_VISIBLE >= 199506

收件人:

#if defined(_POSIX_THREADS)

仅供参考,Makefile 和 CMake 示例仍然存在问题,但与特定问题无关。

有关newlib 问题的更多详细信息,请参阅https://github.com/RIOT-OS/RIOT/issues/10443

【讨论】:

    【解决方案2】:

    好的,首先,确保将工具链 gcc 添加到路径中(参见wiki

    然后,在 github repothis associated page 的基础上,您可以查看实际使用 CMake 和 RIOT 的人的示例(这不是我的情况,显然也不是 RIOT 开发人员的情况),他做了自定义文件来查找 RIOT 和目标板,所以我认为它应该作为起点有所帮助。

    一旦你有 RIOT 检测工作,如果 pthread 问题仍然存在,在你按照 Fred 的建议手动编辑系统文件之前,我会考虑尝试从 CMake 强制 pthread 检测并提示 RIOT:

    find_package (Threads REQUIRED PATHS ${RIOT_ROOT}/sys/posix/pthread/include NO_DEFAULT_PATH)
    

    EDIT 重新思考这个问题,也许我应该澄清一些事情: 我认为最重要的想法是您根据the one from the polymcu repo 正确重新格式化您的CMakeLists.txt 以正确设置交叉编译(尤其是设置CMAKE_SYSTEM_NAME)。 一旦 CMake 了解它是交叉编译,它就不应该使用 POSIX,这应该导致系统的 __POSIX_VISIBLE >= 199506 部分包含评估为 false,从而无需任何手动编辑。 这也是为什么,我提出的find_package 命令是最后的手段,以防万一,应该立即使用。

    当务之急是正确配置您的 CMake,这样问题就会自行解决。

    【讨论】:

    • 我想指出,由于这个问题,使用 Makefile 构建的所有 RIOT POSIX 测试在使用 gnu99 编译时都会出现相同的编译器错误。命令是:RIOT/tests/pthread$ CFLAGS=-std=gnu99 make BOARD=bluepill
    • 是的,显然...gnu99 导致 __POSIX_VISIBLE >= 199506 评估为真...
    • gnu99 表示使用 gnu 编译器扩展,而不是 c 库在与正确的 RIOT OS 系统头文件冲突的非标准头文件中定义 pthread。很明显,c 库不是 POSIX 系统库。
    • 但这是标志的结果,请参阅herehere 示例
    猜你喜欢
    • 1970-01-01
    • 2017-08-25
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多