Skip to content
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

Handle differences in math headers compiling with Clang #2352

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

metcalf
Copy link

@metcalf metcalf commented Sep 7, 2021

Problem

Attempting to compile for unit testing using Clang fails due to differences in the math headers with the errors below.

ERROR: /Users/andrew/code/arduino-particle-bazel-demo/particle/src/BUILD:3:17: Compiling src/particle-bazel-demo.cpp failed: (Aborted): wrapped_clang failed: error executing command external/local_config_cc/wrapped_clang '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -O0 -DDEBUG '-std=c++11' ... (remaining 143 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
In file included from src/particle-bazel-demo.cpp:10:
In file included from bazel-out/darwin_arm64-fastbuild/bin/lib/_virtual_includes/Adafruit_GFX_RK/Adafruit_GFX.h:11:
In file included from bazel-out/darwin_arm64-fastbuild/bin/external/io_particle_device_os/_virtual_includes/user/WProgram.h:1:
bazel-out/darwin_arm64-fastbuild/bin/external/io_particle_device_os/_virtual_includes/user/Arduino.h:197:7: error: no member named 'isnan' in namespace 'std'; did you mean '::isnan'?
using std::isnan;
      ^~~~~~~~~~
      ::isnan
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/math.h:523:1: note: '::isnan' declared here
isnan(_A1 __lcpp_x) _NOEXCEPT
^
In file included from src/particle-bazel-demo.cpp:10:
In file included from bazel-out/darwin_arm64-fastbuild/bin/lib/_virtual_includes/Adafruit_GFX_RK/Adafruit_GFX.h:11:
In file included from bazel-out/darwin_arm64-fastbuild/bin/external/io_particle_device_os/_virtual_includes/user/WProgram.h:1:
bazel-out/darwin_arm64-fastbuild/bin/external/io_particle_device_os/_virtual_includes/user/Arduino.h:201:7: error: no member named 'isinf' in namespace 'std'; did you mean '::isinf'?
using std::isinf;
      ^~~~~~~~~~
      ::isinf
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/math.h:473:1: note: '::isinf' declared here
isinf(_A1 __lcpp_x) _NOEXCEPT
^
2 errors generated.
ERROR: /private/var/tmp/_bazel_andrew/a4c7ff0b81f89f303b386f9cf19fd00e/external/io_particle_device_os/BUILD.bazel:1:11: Compiling wiring/src/spark_wiring_usbserial.cpp failed: (Aborted): wrapped_clang failed: error executing command external/local_config_cc/wrapped_clang '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -O0 -DDEBUG '-std=c++11' ... (remaining 131 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
external/io_particle_device_os/wiring/src/spark_wiring_usbserial.cpp:68:14: error: no member named 'max' in namespace 'std'
        return std::max(-1, (int)HAL_USB_USART_Receive_Data(_serial, false));
               ~~~~~^
external/io_particle_device_os/wiring/src/spark_wiring_usbserial.cpp:73:15: error: no member named 'max' in namespace 'std'
  return std::max(0, (int)HAL_USB_USART_Available_Data_For_Write(_serial));
         ~~~~~^
external/io_particle_device_os/wiring/src/spark_wiring_usbserial.cpp:78:14: error: no member named 'max' in namespace 'std'
        return std::max(0, (int)HAL_USB_USART_Available_Data(_serial));
               ~~~~~^
external/io_particle_device_os/wiring/src/spark_wiring_usbserial.cpp:84:17: error: no member named 'max' in namespace 'std'
    return std::max(0, (int)HAL_USB_USART_Send_Data(_serial, byte));
           ~~~~~^
external/io_particle_device_os/wiring/src/spark_wiring_usbserial.cpp:101:14: error: no member named 'max' in namespace 'std'
        return std::max(-1, (int)HAL_USB_USART_Receive_Data(_serial, true));
               ~~~~~^
5 errors generated.

Solution

Add clang-specific preprocessor directives to handle these cases. There appears to be precedent for clang-specific directives in this project:
https://github.com/particle-iot/device-os/search?q=__clang__

Steps to Test

I wrote a demo project to use Bazel and Google Test with Particle for unit testing. To make it compile successfully, I had to include the changes from this PR as a patch:
https://github.com/metcalf/arduino-particle-bazel-demo/blob/main/tools/io_particle_device_os.patch

Example App

N/A

References

Links to the Community, Docs, Other Issues, etc..


Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

@@ -24,6 +24,11 @@
******************************************************************************
*/

#ifdef __clang__
Copy link
Member

Choose a reason for hiding this comment

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

This does not need to be __clang__-specific.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed

@@ -193,6 +193,9 @@ typedef volatile uint32_t RwReg;
// C++ only
#ifdef __cplusplus

#ifndef __clang__
Copy link
Member

Choose a reason for hiding this comment

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

I would suggest also not using targeting __clang__ specifically and instead include <cmath> if compiling as __cplusplus and math.h otherwise, which should resolve the problem.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed. Note that my fix still includes math.h in all cases since I think that's required for backwards compatibility with user code as described in the new comment. My C experience is limited so I'm prepared to be wrong about that!

I also chose to put the conditional include of <cmath> adjacent to the include of math.h since I think it's clearer even though it requires a separate #ifndef __cplusplus guard.

// In order to support compiling with Clang, explicitly include cmath here since the Clang version
// of the math.h header included above does not include cmath. This is a no-op compiling with GCC
// since the GCC version of math.h includes cmath. Replacing the math.h include above
#include <cmath>
Copy link
Member

Choose a reason for hiding this comment

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

This is now included twice.

Copy link
Author

Choose a reason for hiding this comment

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

Gah, sorry, I caught this locally but forgot to push. Fixed now.

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