用于嵌入式的 cmake:删除 Linux POSIX headers

cmake for embedded: remove Linux POSIX headers

所以,我正在为 RIOT OS 开发一个嵌入式库。因为我的库使用的是 Cmake,而 RIOT 使用的是一个简单的 Makefile,所以我只编译了一个静态库,然后 link 稍后在编译时将其添加到 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 header 文件。因为这是嵌入式的,所以不应该那样做。

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 header 文件?

这是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

问题不在于使用 POSIX headers 嵌入的 CMake。 这是误会的错误。

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

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

您可以通过使用 -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

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

然后,在此 github repo and this 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 to setup the cross-compilation properly (especially setting CMAKE_SYSTEM_NAME) 正确地重新格式化 CMakeLists.txt。 一旦 CMake 明白它是交叉编译的,它就不应该使用 POSIX,这应该导致系统的 __POSIX_VISIBLE >= 199506 部分包含评估为 false,从而消除任何手动编辑的需要。 这也是为什么,我提出的find_package命令是万不得已的,应该马上使用

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