0

I am x-compiling bare metal C++ for ARM Cortex_M7 with the arm-none-eabi-gcc/g++ toolchains and it works fine, flashing nice firmware on my board.

Now, when/if I want to include to "good old" C++ <mutex>, <queue>, <iostream>... files, I get waterfall of compilation errors (I won't bother pasting here as I know these are not relevant..)

Is this expected because these are simply not available and I should act as a man and write my own queue, mutex,... classes by myself as I am doing right now (sounds a bit like reinventing the wheel, though) or am I missing a "sysroot" ? But...Is there such a thing for every single ARM-Cortex_Mx architecture in the world?

I am probably confused by reading this, between sysroot, std, linux and maybe I need to download an appropriate toochain (arm-none-linux-gnueabi-g++ ?) containing a specific 'sysroot' (with all the includes and libs for my target) because I am compiling within a Linux environment even though my target won't run on Linux (bare metal) ?

I am afraid I can't google the appropriate subject (or mis-googled it?)

Thank you for clarifications !

Edit:

  • Error while including and :

    $~>make

    CXX obj/src/hot_queue.o

    In file included from /usr/arm-none-eabi/include/c++/9.2.0/ext/string_conversions.h:43,

             from /usr/arm-none-eabi/include/c++/9.2.0/bits/basic_string.h:6493,
    
             from /usr/arm-none-eabi/include/c++/9.2.0/string:55,
             from /usr/arm-none-eabi/include/c++/9.2.0/stdexcept:39,
             from /usr/arm-none-eabi/include/c++/9.2.0/array:39,
             from /usr/arm-none-eabi/include/c++/9.2.0/tuple:39,
             from /usr/arm-none-eabi/include/c++/9.2.0/mutex:38,
             from src/hot_queue.hpp:27,
             from src/hot_queue.cpp:29:
    

    /usr/arm-none-eabi/include/c++/9.2.0/cstdio:127:11: error: '::printf' has not been declared

    127 | using ::printf;

    | ^~~~~~

/usr/arm-none-eabi/include/c++/9.2.0/cstdio:134:11: error: '::scanf' has not been declared 134 | using ::scanf;

  |           ^~~~~

make: *** [mak/Makefile.sam.in:359: obj/src/hot_queue.o] Error 1

Actually, another good example is : this time g++ does find the proper file...but can't compile it....macro errors:

   ~> make
CXX     obj/src/hot_can.o
CXX     obj/src/hot_main.o
In file included from /usr/arm-none-eabi/include/c++/9.2.0/vector:60,
                 from src/hot_can.hpp:28,
                 from src/hot_can.cpp:30:
/usr/arm-none-eabi/include/c++/9.2.0/bits/stl_algobase.h:246:56: error: macro "min" passed 3 arguments, but takes just 2
  246 |     min(const _Tp& __a, const _Tp& __b, _Compare __comp)
      |                                                        ^
In file included from ./sam/boards/samv71_xplained_ultra/samv71_xplained_ultra.h:40,
                 from src/hot_can.cpp:24:
./sam/utils/compiler.h:810: note: macro "min" defined here
  810 | #define min(a, b)   Min(a, b)
      | 
In file included from /usr/arm-none-eabi/include/c++/9.2.0/vector:60,
                 from src/hot_can.hpp:28,
                 from src/hot_can.cpp:30:
/usr/arm-none-eabi/include/c++/9.2.0/bits/stl_algobase.h:268:56: error: macro "max" passed 3 arguments, but takes just 2
  268 |     max(const _Tp& __a, const _Tp& __b, _Compare __comp)
      |                                                        ^
In file included from ./sam/boards/samv71_xplained_ultra/samv71_xplained_ultra.h:40,
                 from src/hot_can.cpp:24:
./sam/utils/compiler.h:821: note: macro "max" defined here
  821 | #define max(a, b)   Max(a, b)
      | 
In file included from /usr/arm-none-eabi/include/c++/9.2.0/vector:60,
                 from src/hot_can.hpp:28,
                 from src/hot_main.cpp:36:
/usr/arm-none-eabi/include/c++/9.2.0/bits/stl_algobase.h:246:56: error: macro "min" passed 3 arguments, but takes just 2
  246 |     min(const _Tp& __a, const _Tp& __b, _Compare __comp)

EDIT:

Including in my code:

CXX     obj/src/hot_tmc.o
arm-none-eabi-g++  -mcpu=cortex-m7 -mthumb -D__SAMV71Q21B__  -O1 -DDEBUG -D__SAMV71Q21B__ -Dscanf=iscanf -DARM_MATH_CM7=true -Dprintf=iprintf -DBOARD=SAMV71_XPLAINED_ULTRA -I./src -I./inc -I./lib -I./com/boards -I./com/services/clock -I./com/services/gpio -I./com/services/ioport -I./com/services/sleepmgr -I./com/services/sleepmgr/sam -I./com/services/serial -I./com/services/serial/sam_uart -I./com/utils -I./com/utils/stdio/stdio_serial -I./sam/boards -I./sam/boards/samv71_xplained_ultra -I./sam/drivers -I./sam/drivers/afec -I./sam/drivers/matrix -I./sam/drivers/mcan -I./sam/drivers/mpu -I./sam/drivers/pio -I./sam/drivers/pmc -I./sam/drivers/tc -I./sam/drivers/uart -I./sam/drivers/usart -I./sam/utils -I./sam/utils/cmsis/samv71/source/templates -I./sam/utils/fpu -I./sam/utils/header_files -I./sam/utils/cmsis/samv71/include -I./sam/utils/preprocessor -mfloat-abi=softfp -mfpu=fpv5-sp-d16 -mlong-calls -std=gnu++17  -pipe -Wall  -Wpointer-arith -ffunction-sections -fdata-sections -fno-strict-aliasing -Wmain -Wparentheses -Wchar-subscripts -Wcomment -Wformat=2 -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wwrite-strings -Wmissing-declarations -Wsign-compare -Waggregate-return -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls  -Wlong-long -Wunreachable-code -Wcast-align --param max-inline-insns-single=500  -g3 -MD -MP -MQ obj/src/hot_tmc.o -c src/hot_tmc.cpp -o obj/src/hot_tmc.o
In file included from /usr/arm-none-eabi/include/c++/9.2.0/ext/string_conversions.h:43,
                 from /usr/arm-none-eabi/include/c++/9.2.0/bits/basic_string.h:6493,
                 from /usr/arm-none-eabi/include/c++/9.2.0/string:55,
                 from /usr/arm-none-eabi/include/c++/9.2.0/stdexcept:39,
                 from /usr/arm-none-eabi/include/c++/9.2.0/array:39,
                 from /usr/arm-none-eabi/include/c++/9.2.0/tuple:39,
                 from /usr/arm-none-eabi/include/c++/9.2.0/mutex:38,
                 from src/hot_tmc.cpp:26:
/usr/arm-none-eabi/include/c++/9.2.0/cstdio:127:11: error: '::printf' has not been declared
  127 |   using ::printf;
      |           ^~~~~~
/usr/arm-none-eabi/include/c++/9.2.0/cstdio:134:11: error: '::scanf' has not been declared
  134 |   using ::scanf;
      |           ^~~~~
In file included from src/hot_tmc.cpp:30:
src/hot_log.hpp: In member function 'void LOG::LogThis(LOG::log_ID, const char*, const char*, int, Params&& ...)':
src/hot_log.hpp:132:13: error: there are no arguments to 'printf' that depend on a template parameter, so a declaration of 'printf' must be available [-fpermissive]
  132 |             printf(buffer);
      |             ^~~~~~
src/hot_log.hpp:132:13: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
src/hot_log.hpp:136:7: error: there are no arguments to 'printf' that depend on a template parameter, so a declaration of 'printf' must be available [-fpermissive]
  136 |       printf(" %s\r\n", RESET);
      |       ^~~~~~
src/hot_tmc.cpp: In member function 'void TMC::PrintNewTC(const CANPckt&)':
src/hot_tmc.cpp:94:9: error: 'printf' was not declared in this scope
   94 |         printf("[%d] 0x%2x (%3d)\r\n", i, tcPckt.GetPcktByte(i),  tcPckt.GetPcktByte(i) );
      |         ^~~~~~
src/hot_tmc.cpp:31:1: note: 'printf' is defined in header '<cstdio>'; did you forget to '#include <cstdio>'?
   30 | #include "hot_log.hpp"
  +++ |+#include <cstdio>
   31 | 
In file included from src/hot_tmc.cpp:30:
src/hot_log.hpp: In instantiation of 'void LOG::LogThis(LOG::log_ID, const char*, const char*, int, Params&& ...) [with Params = {const char (&)[28]}]':
src/hot_tmc.cpp:65:9:   required from here
src/hot_log.hpp:132:19: error: 'printf' was not declared in this scope
  132 |             printf(buffer);
      |             ~~~~~~^~~~~~~~
src/hot_log.hpp:1:1: note: 'printf' is defined in header '<cstdio>'; did you forget to '#include <cstdio>'?
  +++ |+#include <cstdio>
    1 | /* ----------------------------------------------------------------------------
src/hot_log.hpp:134:19: error: 'printf' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
  134 |             printf(std::forward<Params>(params)...);
      |             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/hot_log.hpp:136:13: error: 'printf' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
  136 |       printf(" %s\r\n", RESET);
      |       ~~~~~~^~~~~~~~~~~~~~~~~~
src/hot_log.hpp: In instantiation of 'void LOG::LogThis(LOG::log_ID, const char*, const char*, int, Params&& ...) [with Params = {const char (&)[32], unsigned char}]':
src/hot_tmc.cpp:69:5:   required from here
src/hot_log.hpp:132:19: error: 'printf' was not declared in this scope
  132 |             printf(buffer);
      |             ~~~~~~^~~~~~~~
src/hot_log.hpp:132:19: note: 'printf' is defined in header '<cstdio>'; did you forget to '#include <cstdio>'?
src/hot_log.hpp:134:19: error: 'printf' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
  134 |             printf(std::forward<Params>(params)...);
      |             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/hot_log.hpp:136:13: error: 'printf' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
  136 |       printf(" %s\r\n", RESET);
      |       ~~~~~~^~~~~~~~~~~~~~~~~~

So indeed the feeling the "printf()" reserved name ovlerloading from ATMEL/Microchip's libraries/drivers, is poisoning the usage of std includes.

bli
  • 93
  • 6
  • 1
    `of compilation errors (I won't bother pasting here as I know these are not relevant.` - please post full compilation line including compiler used and compilation options and for example one or two errors including filenames and line numbers. Are you sure you are using c++ compiler? Are you sure your file is named with cpp extension? `are simply not available` - what compiler version are you using? They are available. `sysroot` - you are compiling for `none` architecture, sysroot is not really relevant `reading this` - this compiles for `linux-gnueabi`. It's not `none`, it's for linux. – KamilCuk Oct 08 '19 at 09:07
  • 1
    Or you can just check if `/usr/arm-none-eabi/include/c++//queue` exists. – KamilCuk Oct 08 '19 at 09:12
  • Thanks for your comments! That is indeed already very interesting: /usr/arm-none-eabi/include/c++/9.2.0/queue does indeed exist, same for mutex. And, yes, all files for g++ are distinguished with .cpp format (again, this is already working fine with my current code/way of working) – bli Oct 08 '19 at 09:38
  • 1
    I believe you should show your code in hot_queue.cpp, at least a smallest possible code that reproduces the same problem. This looks like you defined a symbol used by the implementation. `make CXX` - run `make -n` or `make --debug=j` or remove the `@` from make and show the commands and compile options make uses for the compiler. I could reproduce such error with simple `#define _STDIO_H_` `#include `. Och, did you install newlib? – KamilCuk Oct 08 '19 at 09:40
  • @KamilCuk: It makes perfect sense that a system without I/O lacks `::printf`. – MSalters Oct 08 '19 at 09:43
  • 1
    Check if `/usr/arm-none-eabi/include/stdio.h` exists. Do you get any errors about missing stdio.h or any other standard C header? What distro are you on? @MSalters yes, but generally arm-none-eabi comes with newlib as C standard library implementation and it provides most stub implementations for C and posix I/O, printf should be there at least printf declaration should be there. I can include `mutex` `iostream` `queue` on my system with arm-none-eabi-g++ 9.2.0. – KamilCuk Oct 08 '19 at 09:52
  • This is ARCH Linux (Manjaro) and /usr/arm-none-eabi/include/stdio.h is present. Ha, this is very valuable inputs, so there is definitely something wring with my ecosystem (Makefile?includes?) And printf is working fine (redirected to serial/usb debugger console) but thus probably overloaded by ATMEL's own definition of printf? Ahhh a stupid defined symbol used by the implementation? (did I? or maybe ATMEL did?) – bli Oct 08 '19 at 12:51
  • make --debug=j CXX obj/src/hot_can.o Reaping winning child 0x5616056cc6c0 PID 28093 Live child 0x5616056cc6c0 (obj/src/hot_can.o) PID 28094 In file included from /usr/arm-none-eabi/include/c++/9.2.0/vector:60, from src/hot_can.hpp:28, from src/hot_can.cpp:30: /usr/arm-none-eabi/include/c++/9.2.0/bits/stl_algobase.h:246:56: error: macro "min" passed 3 arguments, but takes just 2 246 | min(const _Tp& __a, const _Tp& __b, _Compare __comp) – bli Oct 08 '19 at 12:54
  • I have arm-none-eabi-newlib 3.1.0-1 installed – bli Oct 08 '19 at 12:59

1 Answers1

0

<iostream> gives you std::cin and std::cout - standard in and standard out. Those are character devices. But a Cortex-M is often found in deep embedded systems where there's no OS, no keyboard or other I/O. You may also find <fstream> missing for the same reason.

<queue> is entirely different. It has no hardware dependency; it should be present. <mutex> is the one arguable part. Threading is new in C++11, and not all Cortex-M systems may have multi-core systems. Without a multi-core system and without an OS to do thread swapping, threading and mutexes will be hard to implement.

Having said that, the nature of <queue> means that you're probably going to get away with using a Linux version of <queue> from outside your build environment. Dirty, but probably workable.

MSalters
  • 173,980
  • 10
  • 155
  • 350