Snapcraft build fails with -Wpedantic error: ISO C++ forbids

I’m building the benchmark_catkin package with catkin. This is a wrapper which loads a version of Google benchmark. Building worked fine so far on my “local” system. However, when I use snapcraft, it gives me the -Wpedantic error:

In file included from /root/parts/workspace/install/usr/include/x86_64-linux-gnu/bits/fcntl.h:61:0, from /root/parts/workspace/install/usr/include/fcntl.h:35, from /root/parts/workspace/build/benchmark_catkin/benchmark_src-prefix/src/benchmark_src/src/sysinfo.cc:23: /root/parts/workspace/install/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h:355:27: error: ISO C++ forbids zero-size array ‘f_handle’ [-Wpedantic] unsigned char f_handle[0];

The error is pretty clear. Is there an option to be less strict with this ISO C++ standard? I’m wondering why the VM builds this code differently than my “local” catkin build command.

Edit: I can clearly find the reason for this error in the file /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h which is:

/* File handle structure.  */
struct file_handle
{
  unsigned int handle_bytes;
  int handle_type;
  /* File identifier.  */
  unsigned char f_handle[0];
};

But I don’t understand why I’m getting this error only with snapcraft. What can I do? Are there any build options?

I agree, seems odd that you’re getting different behavior locally. I don’t see anything in the code that should be causing this, @sergiusens/@cjp256 any ideas? @prex, any chance you could share your snapcraft.yaml?

Sure, I made this minimal example snapcraft.yaml:

name: nav
base: core18
version: 'w1.0'
summary: The Nav Software 
description: |
  This snap includes the software.

grade: devel
confinement: strict

plugs:
  network:
  network-bind:

parts:

  core-dep:
    plugin: nil
    build-packages:
      - autoconf
      - libtool
      - git

  workspace:
    plugin: catkin-tools
    source: .
    rosinstall-files: [snap/local/snap.rosinstall]
    catkin-packages: [catkin_simple, glog_catkin, gflags_catkin, benchmark_catkin]
    after: [core-dep]

And the snap.rosinstall files with the required catkin wrappers (version is the latest one):

- git:
    local-name: external/catkin_simple
    uri: git@github.com:catkin/catkin_simple.git
    version: 0e62848

- git:
    local-name: external/glog_catkin
    uri: git@github.com:ethz-asl/glog_catkin.git
    version: 1b8eab2

- git:
    local-name: external/gflags_catkin
    uri: git@github.com:ethz-asl/gflags_catkin.git
    version: fc38fc5

- git:
    local-name: external/benchmark_catkin
    uri: git@github.com:ethz-asl/benchmark_catkin.git
    version: 5018b4b

Do the compiler versions match? I assume your project has -Wpedantic conditionally defined, but the behavior may change with different compiler versions… can you see if that flag is being used for your local builds?

Perhaps you can try building it in an ubuntu 18:04 container and see if you get the same results?

Can you provide an example source to build with? I think I need something else for that yaml to build…

gcc -v gives me version 7.5.0 in the VM and 7.4.0 on my “local” system.

In the benchmark_catkin wrapper, I couldn’t find any hint of -Wpedantic in the CMakeLists. In my local catkin config I’m not using any additional CMake Args.

Regarding the C++ version, I tried to add add_definitions(-std=c++11 -Wno-pedantic) to the CMakeLists but with the same result.

No, I’m really just trying to build the benchmark_catkin wrapper, which relies on the three other packages in the .rosinstall file. The Snapcraft.yaml should build like this.

OK, I managed to reproduce, I’ll dig in further and see what I can find… :slight_smile:

1 Like

It looks like the problem comes from the Google Benchmark library, included by benchmark_catkin:

That project’s cmake build enabled pedantic errors:

Interestingly, if we move past the revision pinned by benchmark_catkin, they’ve disabled those flags due to other problems:

So perhaps pinning to a newer release is the answer?

1 Like

Does the plugin use the stage-package’d compiler or the on host one?

Indeed, by removing these flags, it builds fine. However, forking both repos is not a really nice option and I would like to keep benchmark version 1.3.0 for the moment. I would prefer if snapcraft could handle the pedantic flags in the same way as my local system.

I’m not familiar with ros or catkin in particular. The main difference I can see is the weird paths for fcntl.h and friends in the initial error you reported:

In file included from /root/parts/workspace/install/usr/include/x86_64-linux-gnu/bits/fcntl.h:61:0,
from /root/parts/workspace/install/usr/include/fcntl.h:35,
from /root/parts/workspace/build/benchmark_catkin/benchmark_src-prefix/src/benchmark_src/src/sysinfo.cc:23:
/root/parts/workspace/install/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h:355:27: error: ISO C++ forbids zero-size array ‘f_handle’ [-Wpedantic]
unsigned char f_handle[0];

It seems to be including copies of these headers from within your Snapcraft project rather than the system ones in /usr/include. IIRC, the compiler treats certain “system header” directories as special w.r.t warning handling. That probably wouldn’t extend to the local copies of these headers.

So I guess the question is: why is there a copy of the system headers in your part’s install dir, and is it possible to avoid that?

2 Likes

@jamesh That’s my gut feeling as well. The plugin itself installs the build dependencies as staged packages, and those get used because snapcraft incorporates the staged includes.

I have created a simplified version of the plugin (ish) that does not reproduce this w/o using the staged resources, and it works fine.

Though I’m still not sure why the divergence in behavior. In my case, the staged headers/g++ match the host headers/g++…

FWIW: I took at a stab and patched https://github.com/snapcore/snapcraft/blob/master/snapcraft/internal/project_loader/_env.py#L62 to use -idirafter instead of -I, and it builds fine.

Nailed it.

When including system headers, they need to be included with -isystem. When used the pedantic warning/error will be suppressed.

We’ll have to sort out how best to fix this.

man g++

The -isystem and -idirafter options also mark the directory as a system directory, so that it gets the same special treatment that is applied to the standard system directories.

https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html

The header files declaring interfaces to the operating system and runtime libraries often cannot be written in strictly conforming C. Therefore, GCC gives code found in system headers special treatment. All warnings, other than those generated by ‘#warning’ (see Diagnostics), are suppressed while GCC is processing a system header.

2 Likes

I put up a PR that should fix this problem.

In a few hours you can give it a test with:
sudo snap refresh snapcraft --channel edge/pr-2974

2 Likes

Thanks! I will check this in the next few days.

1 Like

Works with the 3.11 release :-). Thanks again for fixing so quickly.

1 Like