2

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

Citrullin
  • 2,269
  • 14
  • 29
  • I'm not sure you can do that while including ``stdlib.h``... can you avoid this include? – Silmathoron Nov 26 '18 at 17:10
  • @Silmathoron I changed it to native in RIOT, so the arm-none-eabi compiler is used. I changed the question. The confusion part is that arm-none-eabi contains header files for pthreads. This shouldn't be there, since arm-none-eabi doesn't target any vendor or operation system. pthreads is something operation system specific. – Citrullin Nov 27 '18 at 01:33
  • I'm a little surprised by that... maybe it's a bug (doubt that) but maybe you're not telling the compiler what you think you are. Could you post the cmake config log? – Silmathoron Nov 27 '18 at 08:25
  • 1
    I don't think that setting -I is enough for cross-compiling. See https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux. I noticed that RIOT OS has this helper script for generating a toolchain file. https://github.com/RIOT-OS/RIOT/blob/master/dist/tools/cmake/generate-xcompile-toolchain.sh – fdk1342 Nov 28 '18 at 05:00
  • @Fred I linked the repo, so you can reproduce it. I am not sure, but I think I already use the toolchain generator. I can reproduce the same issue with a Makefile. You see here (https://github.com/Citrullin/RIOT/commit/7e1d8884ab135ae64cee02c8c1a447015f4325bc) how the Makefile looked like before with cmake. – Citrullin Dec 01 '18 at 02:44
  • @Silmathoron I edited the post and added links to pastebin. Added all logs. I also added the steps to reproduce. – Citrullin Dec 01 '18 at 02:48

2 Answers2

1

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.

fdk1342
  • 3,274
  • 1
  • 16
  • 17
-1

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.

Silmathoron
  • 1,781
  • 1
  • 15
  • 32
  • I want to point out that all RIOT POSIX tests built with Makefiles have the same compiler error when compiled with `gnu99` because of this issue. The command is: `RIOT/tests/pthread$ CFLAGS=-std=gnu99 make BOARD=bluepill` – fdk1342 Dec 01 '18 at 10:32
  • yes, obviously... ``gnu99`` leads ``__POSIX_VISIBLE >= 199506`` to evaluate to true... – Silmathoron Dec 01 '18 at 10:37
  • `gnu99` means to use gnu compiler extensions, not for the c library to define pthread in a non-standard header file that conflicts with the correct RIOT OS system header file. It seems clear that the c library is not the POSIX system library. – fdk1342 Dec 01 '18 at 10:48
  • but it is a consequence of the flag, see [here](https://stackoverflow.com/q/38139631/5962321) and [here](https://stackoverflow.com/a/52198294/5962321) for examples – Silmathoron Dec 01 '18 at 10:54