blackmagic-debug / blackmagic

In application debugger for ARM Cortex microcontrollers.
GNU General Public License v3.0
3.2k stars 764 forks source link

Ubuntu 22.04 compilation issue: "error: ‘O_CLOEXEC’ undeclared (first use in this function); did you mean ‘FD_CLOEXEC’?" #1933

Open CIPop opened 2 days ago

CIPop commented 2 days ago

I tried gcc 10,11 and 12 with the same result.

Repro on 6.5.0-41-generic #41~22.04.2-Ubuntu :

  1. meson setup build
  2. meson compile or ninja within the \build folder:
[2/119] Compiling C object deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o
FAILED: deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o
gcc-12 -Ideps/hidapi/linux/libhidapi-hidraw.a.p -Ideps/hidapi/linux -I../deps/hidapi/linux -Ideps/hidapi/hidapi -I../deps/hidapi/hidapi -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -std=c11 -Os -g -fPIC -pthread -MD -MQ deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o -MF deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o.d -o deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o -c ../deps/hidapi/linux/hid.c
../deps/hidapi/linux/hid.c: In function ‘utf8_to_wchar_t’:
../deps/hidapi/linux/hid.c:111:32: warning: implicit declaration of function ‘wcsdup’; did you mean ‘wcscmp’? [-Wimplicit-function-declaration]
  111 |                         return wcsdup(L"");
      |                                ^~~~~~
      |                                wcscmp
../deps/hidapi/linux/hid.c:111:32: warning: returning ‘int’ from a function with return type ‘wchar_t *’ {aka ‘int *’} makes pointer from integer without a cast [-Wint-conversion]
  111 |                         return wcsdup(L"");
      |                                ^~~~~~~~~~~
../deps/hidapi/linux/hid.c: In function ‘get_hid_report_descriptor’:
../deps/hidapi/linux/hid.c:361:48: error: ‘O_CLOEXEC’ undeclared (first use in this function); did you mean ‘FD_CLOEXEC’?
  361 |         rpt_handle = open(rpt_path, O_RDONLY | O_CLOEXEC);
      |                                                ^~~~~~~~~
      |                                                FD_CLOEXEC
../deps/hidapi/linux/hid.c:361:48: note: each undeclared identifier is reported only once for each function it appears in
../deps/hidapi/linux/hid.c: In function ‘parse_hid_vid_pid_from_uevent_path’:
../deps/hidapi/linux/hid.c:450:47: error: ‘O_CLOEXEC’ undeclared (first use in this function); did you mean ‘FD_CLOEXEC’?
  450 |         handle = open(uevent_path, O_RDONLY | O_CLOEXEC);
      |                                               ^~~~~~~~~
      |                                               FD_CLOEXEC
../deps/hidapi/linux/hid.c: In function ‘parse_uevent_info’:
../deps/hidapi/linux/hid.c:552:46: warning: implicit declaration of function ‘strdup’; did you mean ‘strcmp’? [-Wimplicit-function-declaration]
  552 |                         *product_name_utf8 = strdup(value);
      |                                              ^~~~~~
      |                                              strcmp
../deps/hidapi/linux/hid.c:552:44: warning: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  552 |                         *product_name_utf8 = strdup(value);
      |                                            ^
../deps/hidapi/linux/hid.c:556:45: warning: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  556 |                         *serial_number_utf8 = strdup(value);
      |                                             ^
../deps/hidapi/linux/hid.c: In function ‘create_device_info_for_device’:
../deps/hidapi/linux/hid.c:634:51: warning: pointer/integer type mismatch in conditional expression
  634 |         cur_dev->path = dev_path? strdup(dev_path): NULL;
      |                                                   ^
../deps/hidapi/linux/hid.c:667:62: warning: assignment to ‘wchar_t *’ {aka ‘int *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  667 |                                 cur_dev->manufacturer_string = wcsdup(L"");
      |                                                              ^
../deps/hidapi/linux/hid.c:693:54: warning: assignment to ‘wchar_t *’ {aka ‘int *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  693 |                         cur_dev->manufacturer_string = wcsdup(L"");
      |                                                      ^
../deps/hidapi/linux/hid.c:700:54: warning: assignment to ‘wchar_t *’ {aka ‘int *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  700 |                         cur_dev->manufacturer_string = wcsdup(L"");
      |                                                      ^
../deps/hidapi/linux/hid.c:708:54: warning: assignment to ‘wchar_t *’ {aka ‘int *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  708 |                         cur_dev->manufacturer_string = wcsdup(L"");
      |                                                      ^
../deps/hidapi/linux/hid.c:750:67: warning: pointer/integer type mismatch in conditional expression
  750 |                         cur_dev->path = dev_path? strdup(dev_path): NULL;
      |                                                                   ^
../deps/hidapi/linux/hid.c:753:106: warning: pointer/integer type mismatch in conditional expression
  753 |                         cur_dev->serial_number = prev_dev->serial_number? wcsdup(prev_dev->serial_number): NULL;
      |                                                                                                          ^
../deps/hidapi/linux/hid.c:756:124: warning: pointer/integer type mismatch in conditional expression
  756 |                         cur_dev->manufacturer_string = prev_dev->manufacturer_string? wcsdup(prev_dev->manufacturer_string): NULL;
      |                                                                                                                            ^
../deps/hidapi/linux/hid.c:757:109: warning: pointer/integer type mismatch in conditional expression
  757 |                         cur_dev->product_string = prev_dev->product_string? wcsdup(prev_dev->product_string): NULL;
      |                                                                                                             ^
../deps/hidapi/linux/hid.c: In function ‘hid_open_path’:
../deps/hidapi/linux/hid.c:1001:50: error: ‘O_CLOEXEC’ undeclared (first use in this function); did you mean ‘FD_CLOEXEC’?
 1001 |         dev->device_handle = open(path, O_RDWR | O_CLOEXEC);
      |                                                  ^~~~~~~~~
      |                                                  FD_CLOEXEC
[3/119] Generating version.h with a custom command
ninja: build stopped: subcommand failed.
CIPop commented 2 days ago

Workaround:

diff --git a/meson.build b/meson.build
index 44fc844f..01ed86f4 100644
--- a/meson.build
+++ b/meson.build
@@ -35,7 +35,6 @@ project(
        license: 'GPL-3.0-or-later OR BSD-3-Clause OR MIT',
        # license_files: ['COPYING', 'COPYING-BSD', 'COPYING-MIT'], # Only available in meson 1.1.0
        default_options: [
-               'c_std=c11',
                'optimization=s',
                'debug=true',
                # 'warning_level=3', # TODO: Enable by default when all warnings are fixed
dragonmux commented 2 days ago

Thank you for this report, however this is an issue on the HIDAPI fork, not this repo. It was already addressed in commit 9a5cb9f which is where the hidapi-0.14.0-meson tag should point which is what the Meson .wrap file points to in this repo.

Please run rm -rf deps/hidapi on your working copy in the root of the working copy and retry your build - you appear to have an out of date HIDAPI clone.

Please note that "just" removing the C standard line is not actually the correct fix as this causes the library to be built with whatever standard the compiler defaults to. It very specifically needs an older GNU mode, hence how we fixed the issue on the fork.

CIPop commented 1 day ago

I cloned again:

git clone https://github.com/blackmagic-debug/blackmagic
cd blackmagic
meson setup build
cd build/
ninja

I have verified that deps/hidapi does indeed contain the fix:

cat deps/hidapi/meson.build
# SPDX-License-Identifier: BSD-3-Clause
# SPDX-FileCopyrightText: 2023 Rachel Mant <git@dragonmux.network>

project(
        'hidapi',
        'c',
        version: files('VERSION'),
        meson_version: '>=0.58.0',
        license: 'BSD-3-Clause OR GPL-3.0-only',
        default_options: [
                'c_std=gnu99',           <---------------------------
                'warning_level=3',
                'b_pie=true',
                'b_lto=true',
                'cpp_eh=s',
                'buildtype=release',
                'b_ndebug=if-release',
        ]
)

It looks like the root meson.build's default_options is overriding the sub-project configuration. Unfortunately, this is my first interaction with Meson build (I'm used to CMake.)

This is the compiler invocation with the current root meson.build showing that -std=c11 is picked instead of the expected g99.

FAILED: deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o gcc-12 -Ideps/hidapi/linux/libhidapi-hidraw.a.p -Ideps/hidapi/linux -I../deps/hidapi/linux -Ideps/hidapi/hidapi -I../deps/hidapi/hidapi -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -std=c11 -Os -g -fPIC -pthread -MD -MQ deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o -MF deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o.d -o deps/hidapi/linux/libhidapi-hidraw.a.p/hid.c.o -c ../deps/hidapi/linux/hid.c ../deps/hidapi/linux/hid.c: In function ‘utf8_to_wchar_t’:

CIPop commented 1 day ago

Different workaround:

diff --git a/meson.build b/meson.build
index 44fc844f..054ec053 100644
--- a/meson.build
+++ b/meson.build
@@ -35,7 +35,7 @@ project(
        license: 'GPL-3.0-or-later OR BSD-3-Clause OR MIT',
        # license_files: ['COPYING', 'COPYING-BSD', 'COPYING-MIT'], # Only available in meson 1.1.0
        default_options: [
-               'c_std=c11',
+               'c_std=gnu99',
                'optimization=s',
                'debug=true',
                # 'warning_level=3', # TODO: Enable by default when all warnings are fixed
CIPop commented 1 day ago

I found this issue: https://github.com/mesonbuild/meson/issues/2612#issuecomment-343698235

In Meson you can never, ever change the value of existing options inside your build files. You can only specify a new default value for options that do not exist yet. Global options are shared for all projects. When a subproject is called, the option already exists and has a value, thus it can not be changed.

This is a bit odd since I would expect dependencies to come up with their own defaults. Looks like a different mechanism needs to be used in this case to avoid the root meson.build defining dependency-level configurations?

dragonmux commented 1 day ago

To complete this picture, as we're not seeing this issue in CI or locally, what version of Meson are you running? (meson --version)

Regarding your proposed fix that edits the project's main meson.build: unfortunately that won't work out because GNU modes subtly change semantics, and particularly downgrading the standard version is no-go as we are depending on C11 features. It's troubling in particular that the existing mitigation is not seeming to work for you either.

Note that project() block options are not global, they're project-level - global options can only be set with add_global_arguments()/add_global_link_arguments() which we explicitly never do.