cmake for embedded: remove Linux POSIX headers

855 views Asked by At

So, I am developing an embedded library for RIOT OS. Since my library is using Cmake, but RIOT uses a simple Makefile, I just compile a static library and link this later to RIOT while compile time. So I compile the library: I pass all the include files to the CMAKE_C_FLAGS This is needed, since my library uses pthreads and RIOT has support for it.

-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" .

So that works fine. But somehow cmake also tries to include linux header files for posix. Since this is embedded, it shouldn't do that.

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 */

So, my question: How can I tell cmake not to include the linux header files?

This is the current CMakeList.txt I use.

/e I tried the same with a Makefile. Same issue appears here.

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 {
        ^~~~~~~~~~~

There are more of these duplicate definition errors. Looks like they are all of the same nature.

Steps to reproduce:

  1. Clone this repository (branch: iota_new_implementation)

  2. cd into the folder examples/iota_transaction_node

  3. Execute make

Version with Makefile. Commit: 7e1d8884ab135ae64cee02c8c1a447015f4325bc

Version with CMake. Commit: dbf32e727889afa3efb466cfdc8561e697af48b0

USEPKG += iota-wallet

in the Makefile of the example refers to this package. This Makefile is used to make the static library.

Cmake Log:

CmakeError.log

CMakeOutput.log

Console Output

Makefile:

Console Output

2

There are 2 answers

0
fdk1342 On BEST ANSWER

The issue isn't CMake for embedded using POSIX headers. This is a misunderstanding of the error.

I think the confusion comes from the line Scanning dependencies of target iota_wallet and then [ 11%] Building C object CMakeFiles/iota_wallet.dir/src/iota/addresses.c.obj. These are two different steps neither of them involving CMake. CMake is not scanning anything. When CMake generates the Makefiles it simply adds the CMakeLists.txt as part of the dependencies of the build. This is so updating CMakeLists.txt will regenerate new Makefiles when running make. When it does this it prints the Scanning dependencies....

The actual problem occurs compiling the source code with arm-none-eabi. This compiler ships with newlib as its c library. For whatever reason newlib contains some header files for pthreads. Whenever you include a header file like stdint.h or stdlib.h in the source code it includes sys/types.h which then includes sys/_pthreadtypes.h. This conflicts with the pthreads header files shipped with RIOT.

You can work around the issue by compiling with -std=c99.

Or you can work around the issue by edit the file /usr/arm-none-eabi/include/sys/_pthreadtypes.h.

Change:

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

To:

#if defined(_POSIX_THREADS)

FYI, The Makefile and CMake examples still have issues but it has nothing to do with particular issue.

See https://github.com/RIOT-OS/RIOT/issues/10443 for further details about the newlib problem.

4
Silmathoron On

Ok, first of all, make sure you added the toolchain gcc to the path (cf. wiki)

Then, building on this github repo and this associated page, you can have a look at the examples of someone who actually used CMake with RIOT (which is not my case, nor apparently that of the RIOT developers), he made custom files to find RIOT and target boards so I think it should be helpful as a starting point.

Once you have RIOT detection working, if the pthread problem persists, before you manually edit a system file as suggested by Fred, I would consider trying to force the pthread detection from CMake with the hints towards RIOT:

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

EDIT rethinking about the question, maybe I should clarify a few things: I think the most important think is that you properly reformat your CMakeLists.txt based on the one from the polymcu repo to setup the cross-compilation properly (especially setting CMAKE_SYSTEM_NAME). Once CMake understands that it's cross-compiling, it should not be using POSIX, which should lead the __POSIX_VISIBLE >= 199506 part of the system include to evaluate to false, thus removing the need for any manual edit. This is also why, the find_package command I proposed is a last resort, just in case, and should not be used right away.

The priority is to configure your CMake properly, which should make the problem walk away on its own.