Skip to content

Added c++ linker command to allow to include libstdc++ when linking. #838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

helmut64
Copy link

This is needed otherwise the template C++ container support
are missing. The "compiler.c.elf.cmd" specifies the linker,
the C linker was wrong here and does not work for true C++ apps.

This change does not hurt because when no libstdc++ features are
being used there is no change.

Changed the Arduino function map() into Arduino_map(). This is needed
otherwise it clashes with the C++ template class. e.g.: #include

This is needed otherwise the template C++ container support
are missing. The "compiler.c.elf.cmd" specifies the linker,
the C linker was wrong here and does not work for true C++ apps.

This change does not hurt because when no libstdc++ features are
being used there is no change.

Changed the Arduino function map() into Arduino_map(). This is needed
otherwise it clashes with the C++ template class. e.g.: #include <map>
@helmut64
Copy link
Author

PS: I also added the same changes into the 32-bit Arduino SAMD release.

@@ -127,7 +127,7 @@ void loop(void);

long random(long, long);
void randomSeed(unsigned long);
long map(long, long, long, long, long);
long Arduino_map(long, long, long, long, long);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is a good idea at all. Maybe undefine the other map? Arduino users expect this to work this way, so any sketch that uses it will break ;)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other map is the regular C++ libstdc++ map which is being used in all C++ books, C++ projects, etc.. C++ is now here with this for more than 20 years. It is a fault by Arduino to use this name. It is also little being used compared to the C++ map.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but this is Arduino framework so it should adhere to the well known Arduino API ;) we can not rename or get rid of this all together.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it can be renamed to Arduino_map and then define map to Arduino_map (which could in turn be later undefined to allow for C++ map)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arduino uses the gcc compiler and C runtime which brings all the standard runtime libraries. This goes first and than the Arduino libs are on top of it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, but you tell me with this change how will all sketches and examples out there that use Arduino's "map" work?

code needs to do a #undef map before including <map>
It is now the same as in the SAMD Version
@@ -127,7 +127,8 @@ void loop(void);

long random(long, long);
void randomSeed(unsigned long);
long map(long, long, long, long, long);
long Arduino_map(long, long, long, long, long);
#define map Arduino_map

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to define it as map(a,b,c,d,e) so you can per say have class members named map

@me-no-dev
Copy link
Member

urghh... build breaks... I'll look into this and see what can be done :)

@helmut64
Copy link
Author

If I did something wrong please let me know.

@me-no-dev
Copy link
Member

oh no :) but the define somehow breaks builds and I am not sure yet why. I think that you can click on the details like of the travis ci build and see the errors yourself too. Funny enough, the previous wilder definition did not give any issues.

@helmut64
Copy link
Author

I don't know what is wrong with my checkin. Can you help.

@helmut64
Copy link
Author

@me-no-dev should I reverse the Arduino_map define to be used without parameters?

@me-no-dev
Copy link
Member

sorry, i hoped to have some time for this friday, but could not make it. So far IDF compiles it fine.
Will keep you posted :) Have you tried it with gcc?

@me-no-dev
Copy link
Member

tested :)
the following code compiles fine without any changes (and also g++):

#include <map>
void setup() {
  std::map<char,int> first;
  first['a']=10;
  first['b']=30;
  first['c']=50;
  first['d']=70;
  map(analogRead(34),0,1024,0,100);
}

void loop(){}

@helmut64
Copy link
Author

@me-no-dev thank you for testing.
What is the reason that it says here: "All checks have failed"
Thank you for your support.
Helmut

@stickbreaker
Copy link
Contributor

@helmut64
I would say it has something to do with:


In file included from /home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/map:61:0,

from /home/travis/build/espressif/arduino-esp32/libraries/BLE/src/BLEDevice.h:14,

from /tmp/tmpr1dDVY/src/BLE_scan.ino:6:

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:162:11: error: macro "map" requires 5 arguments, but only 1 given

map()

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:175:48: error: macro "map" requires 5 arguments, but only 2 given

const allocator_type& __a = allocator_type())

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:185:25: error: macro "map" requires 5 arguments, but only 1 given

map(const map& __x)

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:196:20: error: macro "map" requires 5 arguments, but only 1 given

map(map&& __x)

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:213:48: error: macro "map" requires 5 arguments, but only 3 given

const allocator_type& __a = allocator_type())

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:219:36: error: macro "map" requires 5 arguments, but only 1 given

map(const allocator_type& __a)

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:223:52: error: macro "map" requires 5 arguments, but only 2 given

map(const map& __m, const allocator_type& __a)

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:227:47: error: macro "map" requires 5 arguments, but only 2 given

map(map&& __m, const allocator_type& __a)

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:233:70: error: macro "map" requires 5 arguments, but only 2 given

map(initializer_list<value_type> __l, const allocator_type& __a)

^

/home/travis/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:240:31: error: macro "map" requires 5 arguments, but only 3 given

const allocator_type& __a)

chuck.

@helmut64
Copy link
Author

@stickbreaker I don't know where the BLE_scan.ino comes from.
In my code using C++ map functions on Arduino I do:
#undef min
#undef max
#undef map
#include
#include
This way I don't use the Arduino map.
In the past I just ad a define map Arduino_map without parameters, that is probably why it was working. But than @me-no-dev recommended to add the parameters. I change it back to my previous version.
Thank you for your feedback.
Regards Helmut

@me-no-dev
Copy link
Member

@helmut64 you do not need any of those edits to use C++ map ;) I executed the above code WITHOUT applying this PR and it is fine.

@helmut64
Copy link
Author

helmut64 commented Nov 27, 2017

@me-no-dev when don't redefine the map in Arduino.h, I get the following error: (on SAMD and ESP32)
In file included from /var/folders/r6/_hqzqjnd5wjd5pc7f23rms9c0000gn/T/arduino_build_249479/sketch/RadioTest.ino.cpp:1:0:
/Users/helmut/Documents/Arduino/hardware/espressif/esp32/cores/esp32/Arduino.h:129:6: note: candidates are: long int map(long int, long int, long int, long int, long int)
long map(long, long, long, long, long);
^
In file included from /Users/helmut/Documents/Arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/map:61:0,
from /Users/helmut/Documents/Arduino/libraries/RadioShuttle/RadioShuttle.h:30,
from /Volumes/Data/work/mbed-work/STM_MyHome_L4/RadioShuttleLib/examples/RadioTest/RadioTest.ino:10:
/Users/helmut/Documents/Arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:96:11: note: template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map
class map
^
In file included from /Volumes/Data/work/mbed-work/STM_MyHome_L4/RadioShuttleLib/examples/RadioTest/RadioTest.ino:10:0:
/Users/helmut/Documents/Arduino/libraries/RadioShuttle/RadioShuttle.h:537:5: error: reference to 'map' is ambiguous
map<devid_t, SignalStrengthEntry> _signals;

 ^

In file included from /var/folders/r6/_hqzqjnd5wjd5pc7f23rms9c0000gn/T/arduino_build_249479/sketch/RadioTest.ino.cpp:1:0:
/Users/helmut/Documents/Arduino/hardware/espressif/esp32/cores/esp32/Arduino.h:129:6: note: candidates are: long int map(long int, long int, long int, long int, long int)
long map(long, long, long, long, long);
^
In file included from /Users/helmut/Documents/Arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/map:61:0,
from /Users/helmut/Documents/Arduino/libraries/RadioShuttle/RadioShuttle.h:30,
from /Volumes/Data/work/mbed-work/STM_MyHome_L4/RadioShuttleLib/examples/RadioTest/RadioTest.ino:10:
/Users/helmut/Documents/Arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/bits/stl_map.h:96:11: note: template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map
class map
^

@me-no-dev
Copy link
Member

please show me the code you are compiling.

@helmut64
Copy link
Author

@me-no-dev the project is huge, here is an extract of the .h file moved into an simple App.
ArduinoMapTest.zip

@me-no-dev
Copy link
Member

I changed map to std::map in your sketch and all is fine :)

@helmut64
Copy link
Author

@me-no-dev great, I have many more cases in my code and the map problems are only on Arduino, I do now the following after include:
#ifdef ARDUINO
#define map std::map // map clashes with Arduino map()
#endif

Thank you.

In platforms.txt, the compiler.c.elf.cmd=xtensa-esp32-elf-gcc is somehow not right and should be "xtensa-esp32-elf-g++", on the SAMD architecture it does not work without the g++ linker.

Should I continue this patch the the platforms change only, or should we close it because it works.

@me-no-dev
Copy link
Member

OK, now let's discuss the g++ thing :) Can you show me an example where g++ will make a difference compared to gcc? Not on SAMD but on ESP32 ;)

ESP-IDF also compiles with gcc and AFAIK it should not make any difference.

@helmut64
Copy link
Author

The ESP32 Arduino linking works fine and all library C++ container functions are included as exspected. The case can be closed.

FYI: Below is the error I am getting on the samd platform, changing the compiler.c.elf.cmd to g++ is the workaround. Somehow on Arduino ESP32 it works fine even using gcc as a linker.

RadioShuttle/RadioShuttle.cpp.o: In function _M_insert<const RadioShuttle::RadioEntry&>': …/arm-none-eabi-gcc/4.8.3-2014q1/arm-none-eabi/include/c++/4.8.3/bits/stl_list.h:1562: undefined reference to std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
RadioShuttle/RadioShuttle.cpp.o: In function std::_Rb_tree_iterator<std::pair<int const, RadioShuttle::AppEntry> >::operator--()': …/arm-none-eabi-gcc/4.8.3-2014q1/arm-none-eabi/include/c++/4.8.3/bits/stl_tree.h:204: undefined reference to std::_Rb_tree_decrement(std::_Rb_tree_node_base*)'
RadioShuttle/RadioShuttle.cpp.o: In function _M_insert_<std::pair<int, RadioShuttle::AppEntry> >': …/arm-none-eabi-gcc/4.8.3-2014q1/arm-none-eabi/include/c++/4.8.3/bits/stl_tree.h:1025: undefined reference to std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'

@me-no-dev
Copy link
Member

The issues you see are probably connected to the ARM toolchain that you use for compiling :)
Closing this now ;)

@me-no-dev me-no-dev closed this Nov 28, 2017
@helmut64
Copy link
Author

Dear @me-no-dev , thank you for working with me on this. I have to say your support is supior, which everyone can see following the Issues and Poll requests.

Thank you. Helmut (from Hannover Germany)

@me-no-dev
Copy link
Member

@helmut64 thanks for the good words :) You are very welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants