Current Arduplane has a compiler error: acos not found?

I’m getting a compiler error trying to build the current master Ardupilot. How do I fix this ?

git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
git submodule update --init --recursive
./waf configure --board Pixhawk1
./waf plane

Compilation terminated due to -Wfatal-errors.

In file included from …/…/libraries/AP_Common/missing/cmath:3:0,
from …/…/libraries/AP_HAL/CAN.h:23,
from …/…/libraries/AP_HAL/HAL.h:17,
from …/…/libraries/AP_HAL/AP_HAL_Main.h:19,
from …/…/libraries/AP_HAL/AP_HAL.h:8,
from …/…/libraries/AC_WPNav/AC_WPNav.cpp:1:
/usr/arm-none-eabi/include/c++/7.4.0/cmath:83:11: error: ‘::acos’ has not been declared
using ::acos;
^~~~
compilation terminated due to -Wfatal-errors.

Waf: Leaving directory `/home/me/workspace/ardupilot/build/Pixhawk1’
Build failed
-> task in ‘objs/AC_WPNav’ failed (exit status 1):
{task 140559548615208: cxx AC_Circle.cpp -> AC_Circle.cpp.0.o}
(run with -v to display more information)
-> task in ‘objs/AC_AutoTune’ failed (exit status 1):
{task 140559548814112: cxx AC_AutoTune.cpp -> AC_AutoTune.cpp.0.o}
(run with -v to display more information)
-> task in ‘objs/AC_WPNav’ failed (exit status 1):
{task 140559548615328: cxx AC_Loiter.cpp -> AC_Loiter.cpp.0.o}
(run with -v to display more information)
-> task in ‘objs/APM_Control’ failed (exit status 1):
{task 140559548613888: cxx AP_YawController.cpp -> AP_YawController.cpp.0.o}
(run with -v to display more information)
-> task in ‘objs/APM_Control’ failed (exit status 1):
{task 140559548613648: cxx AP_RollController.cpp -> AP_RollController.cpp.0.o}
(run with -v to display more information)
-> task in ‘objs/AC_WPNav’ failed (exit status 1):
{task 140559548615448: cxx AC_WPNav.cpp -> AC_WPNav.cpp.0.o}
(run with -v to display more information)

dnf list arduino*

Installed Packages
arduino.noarch 1:1.8.5-6.fc29 @updates
arduino-builder.x86_64 1.3.25-1.fc28 @fedora
arduino-core.noarch 1:1.8.5-6.fc29 @updates
arduino-ctags.x86_64 5.8-8.arduino11.fc29 @fedora
arduino-listSerialPortsC.x86_64 1.4.0-3.fc29 @fedora

Also this:

git clone --single-branch --branch ArduPlane-release https://github.com/ArduPilot/ardupilot.git
git submodule update --init --recursive
./waf configure --board Pixhawk1
./waf plane

[16/479] Compiling libraries/AC_PID/AC_HELI_PID.cpp
In file included from /usr/arm-none-eabi/include/c++/7.4.0/cmath:45:0,
from …/…/libraries/AP_Common/missing/cmath:3,
from …/…/libraries/AP_HAL/CAN.h:23,
from …/…/libraries/AP_HAL/HAL.h:17,
from …/…/libraries/AP_HAL/AP_HAL_Main.h:19,
from …/…/libraries/AP_HAL/AP_HAL.h:8,
from …/…/libraries/AC_Fence/AC_Fence.cpp:1:
/usr/arm-none-eabi/include/math.h:314:35: error: macro “fmax” passed 2 arguments, but takes just 1
extern double fmax (double, double);
^
compilation terminated due to -Wfatal-errors.

I’m running Fedora 29.

Please use one of the compilers recommended here:
http://firmware.ardupilot.org/Tools/STM32-tools/

Thanks, I’ll give one of them a try.

Can you recommend a way to install them such that they coexist with another ARM toolset of a newer version ?

I’m digging into this deeper. I’d really like to run the arm-gcc-non-eabi package that ships on Fedora 29. I’m not exactly sure why this error is happening. I don’t see anything in the diff that alerts me to an issue with acos.

$ dnf list arm*

Installed Packages
arm-image-installer.noarch 2.10-1.fc29
arm-none-eabi-binutils-cs.x86_64 1:2.32-1.fc29
arm-none-eabi-gcc-cs.x86_64 1:7.4.0-1.fc29
arm-none-eabi-gcc-cs-c++.x86_64 1:7.4.0-1.fc29

$ diff /usr/arm-none-eabi/include/c++/7.4.0/cmath /home/me/Downloads/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include/c++/6.3.1/cmath


3c3
< // Copyright (C) 1997-2017 Free Software Foundation, Inc.
---
> // Copyright (C) 1997-2016 Free Software Foundation, Inc.
47d46
< #include <bits/std_abs.h>
52a52
> #undef abs
82a83,105
> #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
>   inline _GLIBCXX_CONSTEXPR double
>   abs(double __x)
>   { return __builtin_fabs(__x); }
> #endif
> 
> #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
>   inline _GLIBCXX_CONSTEXPR float
>   abs(float __x)
>   { return __builtin_fabsf(__x); }
> 
>   inline _GLIBCXX_CONSTEXPR long double
>   abs(long double __x)
>   { return __builtin_fabsl(__x); }
> #endif
> 
>   template<typename _Tp>
>     inline _GLIBCXX_CONSTEXPR
>     typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
>                                     double>::__type
>     abs(_Tp __x)
>     { return __builtin_fabs(__x); }
> 
1015d1037
< #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS
1022d1043
< #endif
1148d1168
< #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS
1156d1175
< #endif
1866,1913c1885
< #if __cplusplus > 201402L
< namespace std _GLIBCXX_VISIBILITY(default)
< {
< _GLIBCXX_BEGIN_NAMESPACE_VERSION
< 
<   // [c.math.hypot3], three-dimensional hypotenuse
< #define __cpp_lib_hypot 201603
< 
<   template<typename _Tp>
<     inline _Tp
<     __hypot3(_Tp __x, _Tp __y, _Tp __z)
<     {
<       __x = std::abs(__x);
<       __y = std::abs(__y);
<       __z = std::abs(__z);
<       if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x)
<       return __a * std::sqrt((__x / __a) * (__x / __a)
<                              + (__y / __a) * (__y / __a)
<                              + (__z / __a) * (__z / __a));
<       else
<       return {};
<     }
< 
<   inline float
<   hypot(float __x, float __y, float __z)
<   { return std::__hypot3<float>(__x, __y, __z); }
< 
<   inline double
<   hypot(double __x, double __y, double __z)
<   { return std::__hypot3<double>(__x, __y, __z); }
< 
<   inline long double
<   hypot(long double __x, long double __y, long double __z)
<   { return std::__hypot3<long double>(__x, __y, __z); }
< 
<   template<typename _Tp, typename _Up, typename _Vp>
<     typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
<     hypot(_Tp __x, _Up __y, _Vp __z)
<     {
<       using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type;
<       return std::__hypot3<__type>(__x, __y, __z);
<     }
< _GLIBCXX_END_NAMESPACE_VERSION
< } // namespace
< #endif // C++17
< 
< 
< #if _GLIBCXX_USE_STD_SPEC_FUNCS
---
> #if __STDCPP_WANT_MATH_SPEC_FUNCS__ == 1
[me@Brix ~]$ diff /usr/arm-none-eabi/include/c++/7.4.0/cmath  /home/me/Downloads/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include/c++/6.3.1/cmath 
3c3
< // Copyright (C) 1997-2017 Free Software Foundation, Inc.
---
> // Copyright (C) 1997-2016 Free Software Foundation, Inc.
47d46
< #include <bits/std_abs.h>
52a52
> #undef abs
82a83,105
> #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
>   inline _GLIBCXX_CONSTEXPR double
>   abs(double __x)
>   { return __builtin_fabs(__x); }
> #endif
> 
> #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
>   inline _GLIBCXX_CONSTEXPR float
>   abs(float __x)
>   { return __builtin_fabsf(__x); }
> 
>   inline _GLIBCXX_CONSTEXPR long double
>   abs(long double __x)
>   { return __builtin_fabsl(__x); }
> #endif
> 
>   template<typename _Tp>
>     inline _GLIBCXX_CONSTEXPR
>     typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
>                                     double>::__type
>     abs(_Tp __x)
>     { return __builtin_fabs(__x); }
> 
1015d1037
< #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS
1022d1043
< #endif
1148d1168
< #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS
1156d1175
< #endif
1866,1913c1885
< #if __cplusplus > 201402L
< namespace std _GLIBCXX_VISIBILITY(default)
< {
< _GLIBCXX_BEGIN_NAMESPACE_VERSION
< 
<   // [c.math.hypot3], three-dimensional hypotenuse
< #define __cpp_lib_hypot 201603
< 
<   template<typename _Tp>
<     inline _Tp
<     __hypot3(_Tp __x, _Tp __y, _Tp __z)
<     {
<       __x = std::abs(__x);
<       __y = std::abs(__y);
<       __z = std::abs(__z);
<       if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x)
<       return __a * std::sqrt((__x / __a) * (__x / __a)
<                              + (__y / __a) * (__y / __a)
<                              + (__z / __a) * (__z / __a));
<       else
<       return {};
<     }
< 
<   inline float
<   hypot(float __x, float __y, float __z)
<   { return std::__hypot3<float>(__x, __y, __z); }
< 
<   inline double
<   hypot(double __x, double __y, double __z)
<   { return std::__hypot3<double>(__x, __y, __z); }
< 
<   inline long double
<   hypot(long double __x, long double __y, long double __z)
<   { return std::__hypot3<long double>(__x, __y, __z); }
< 
<   template<typename _Tp, typename _Up, typename _Vp>
<     typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
<     hypot(_Tp __x, _Up __y, _Vp __z)
<     {
<       using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type;
<       return std::__hypot3<__type>(__x, __y, __z);
<     }
< _GLIBCXX_END_NAMESPACE_VERSION
< } // namespace
< #endif // C++17
< 
< 
< #if _GLIBCXX_USE_STD_SPEC_FUNCS
---
> #if __STDCPP_WANT_MATH_SPEC_FUNCS__ == 1

There’s a preview feature. Usually the markup is ``` for block-quotes.

Onto your problem.

We specify the compiler we support in several different places. We’re
kind of picky so we don’t have to worry about multiple compiler versions
too much - but it does mean the compiler we’re currently using is ancient.
We will move forwardat some stage - but it does require a lot of flight
testing to ensure nothing has gone awry.

You might consider installing the compiler we generally use. The prereq
install scripts specify the version:

Thank you.

I understand the project’s predicament - gcc changes quite a bit lately. I also understand how to install the toolchains in the link provided. The main issue is that I work on other ARM projects using STM32F processors and I don’t see an easy way to have both toolchains installed simultaneously without renaming things and adjusting makefiles.

Any ideas ?

I don’t mean to sound ungrateful to the Ardupilot team when I make this comment.

I’m porting a new board into ardupilot by DJGPP compiler and also encounter this problem.
And I found out that in the file AP_HAL/AP_HAL_Marcos.h, such the math functions asin, acos… were redefined.
It works well when I undefine those functions.

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL || CONFIG_HAL_BOARD == HAL_BOARD_LINUX
/*
allow double maths on Linux and SITL to avoid problems with system headers
*/
#define ALLOW_DOUBLE_MATH_FUNCTIONS
#endif

#if !defined(ALLOW_DOUBLE_MATH_FUNCTIONS)
/* give warnings if we use double precision maths functions without
specifying ALLOW_DOUBLE_TRIG_FUNCTIONS. Code should use the
equivalent f function instead (eg. use cosf() instead of
cos()). Individual cpp files that really do need double precision
should define ALLOW_DOUBLE_TRIG_FUNCTIONS before including
AP_Math.h
*/
#define sin(x) DO_NOT_USE_DOUBLE_MATHS()
#define cos(x) DO_NOT_USE_DOUBLE_MATHS()
#define tan(x) DO_NOT_USE_DOUBLE_MATHS()
#define acos(x) DO_NOT_USE_DOUBLE_MATHS()
#define asin(x) DO_NOT_USE_DOUBLE_MATHS()
#define atan(x) DO_NOT_USE_DOUBLE_MATHS()
#define atan2(x,y) DO_NOT_USE_DOUBLE_MATHS()
#define exp(x) DO_NOT_USE_DOUBLE_MATHS()
#define pow(x,y) DO_NOT_USE_DOUBLE_MATHS()
#define sqrt(x) DO_NOT_USE_DOUBLE_MATHS()
#define log2(x) DO_NOT_USE_DOUBLE_MATHS()
#define log10(x) DO_NOT_USE_DOUBLE_MATHS()
#define ceil(x) DO_NOT_USE_DOUBLE_MATHS()
#define floor(x) DO_NOT_USE_DOUBLE_MATHS()
#define round(x) DO_NOT_USE_DOUBLE_MATHS()
#if !HAL_WITH_UAVCAN
// we should do log() and fabs() as well, but can’t because of a conflict in uavcan
#define log(x) DO_NOT_USE_DOUBLE_MATHS()
#define fabs(x) DO_NOT_USE_DOUBLE_MATHS()
#endif
#endif

I’ve put in a PR to fix the build with g++ 7.3.1:

1 Like

Thanks for your help and attention, tridge.

About a month ago I did a build using the specified toolset. Today I did a waf clean and now it can’t find the tools again. And I forgot how I specified them !

To do today’s build I had to modify PATH so the Arm tools could be found. Is there a better way ? How did I do it before ?

Note to self: take better notes ! LOL