Skip to contentSkip to conversation

building rust bindings requires clang headers

libgpiod Kent Gibson 3 participants 8 messages Jun 9, 2023 – Jun 12, 2023 GPIO

lore
Share & tools
lore
#0 lore raw

When trying to build the libgpiod rust bindings on my Debian bullseye VM I get:

Compiling gpiosim-sys v0.1.0 (/home/dev/libgpiod/bindings/rust/gpiosim-sys)
error: failed to run custom build command for gpiosim-sys v0.1.0 (/home/dev/libgpiod/bindings/rust/gpiosim-sys)

Caused by:
process didn't exit successfully: /home/dev/libgpiod/bindings/rust/target/release/build/gpiosim-sys-dfa257ecee3f0e2e/build-script-build (exit status: 101) --- stdout
cargo:rerun-if-changed=../../../tests/gpiosim/gpiosim.h

--- stderr
../../../tests/gpiosim/gpiosim.h:7:10: fatal error: 'stdbool.h' file not found
thread 'main' panicked at 'Unable to generate bindings: ClangDiagnostic("../../../tests/gpiosim/gpiosim.h:7:10: fatal error: 'stdbool.h' file not found\n")', gpiosim-sys/build.rs:27:10
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

The source of the error appears to be bindgen using libclang to parse the gpiosim header, and that failing if the requisite headers are not installed.

If I install them:

apt install libclang-common-11-dev

the build passes.

Can a dependency be added to the autotools configuration to check for the availability of those headers if building the rust bindings? I would add it myself, but I'm not sure how - or if there is some better solution.
The configure.ac already has a AC_HEADER_STDBOOL, but that checks for the gcc headers, not clang.

Cheers,
Kent.

#1 lore raw
Quoted 20 lines · Kent Gibson

When trying to build the libgpiod rust bindings on my Debian bullseye VM I get:

Compiling gpiosim-sys v0.1.0 (/home/dev/libgpiod/bindings/rust/gpiosim-sys)
error: failed to run custom build command for gpiosim-sys v0.1.0 (/home/dev/libgpiod/bindings/rust/gpiosim-sys)

Caused by:
process didn't exit successfully: /home/dev/libgpiod/bindings/rust/target/release/build/gpiosim-sys-dfa257ecee3f0e2e/build-script-build (exit status: 101) --- stdout
cargo:rerun-if-changed=../../../tests/gpiosim/gpiosim.h

--- stderr
../../../tests/gpiosim/gpiosim.h:7:10: fatal error: 'stdbool.h' file not found
thread 'main' panicked at 'Unable to generate bindings: ClangDiagnostic("../../../tests/gpiosim/gpiosim.h:7:10: fatal error: 'stdbool.h' file not found\n")', gpiosim-sys/build.rs:27:10
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

The source of the error appears to be bindgen using libclang to parse the gpiosim header, and that failing if the requisite headers are not installed.

Quoted 8 lines

If I install them:

apt install libclang-common-11-dev

the build passes.

Can a dependency be added to the autotools configuration to check for the availability of those headers if building the rust bindings?

I am not very experienced with autotools, but won't something like this help ?

AC_CHECK_HEADERS([stdbool.h], [], [HEADER_NOT_FOUND_LIB([stdbool.h])])

Quoted 4 lines

I would add it myself, but I'm not sure how - or if there is some better solution.
The configure.ac already has a AC_HEADER_STDBOOL, but that checks for the gcc headers, not clang.

Signature · 1 line
viresh
#2 lore raw
Quoted 25 lines · Viresh Kumar
Quoted 24 lines · Kent Gibson

When trying to build the libgpiod rust bindings on my Debian bullseye VM I get:

Compiling gpiosim-sys v0.1.0 (/home/dev/libgpiod/bindings/rust/gpiosim-sys)
error: failed to run custom build command for gpiosim-sys v0.1.0 (/home/dev/libgpiod/bindings/rust/gpiosim-sys)

Caused by:
process didn't exit successfully: /home/dev/libgpiod/bindings/rust/target/release/build/gpiosim-sys-dfa257ecee3f0e2e/build-script-build (exit status: 101) --- stdout
cargo:rerun-if-changed=../../../tests/gpiosim/gpiosim.h

--- stderr
../../../tests/gpiosim/gpiosim.h:7:10: fatal error: 'stdbool.h' file not found
thread 'main' panicked at 'Unable to generate bindings: ClangDiagnostic("../../../tests/gpiosim/gpiosim.h:7:10: fatal error: 'stdbool.h' file not found\n")', gpiosim-sys/build.rs:27:10
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

The source of the error appears to be bindgen using libclang to parse the gpiosim header, and that failing if the requisite headers are not installed.

If I install them:

apt install libclang-common-11-dev

Quoted 9 lines
Quoted 4 lines

the build passes.

Can a dependency be added to the autotools configuration to check for the availability of those headers if building the rust bindings?

I am not very experienced with autotools, but won't something like this help ?

AC_CHECK_HEADERS([stdbool.h], [], [HEADER_NOT_FOUND_LIB([stdbool.h])])

I think that is what the AC_HEADER_STDBOOL already does - but that detects the gcc header, and the additional check needs to be for the clang header.

Unless you can convince clang to use the gcc headers?

Cheers,
Kent.

Quoted 7 lines
Quoted 4 lines

I would add it myself, but I'm not sure how - or if there is some better solution.
The configure.ac already has a AC_HEADER_STDBOOL, but that checks for the gcc headers, not clang.

Signature · 1 line
viresh
#3 lore raw
Quoted 5 lines · Kent Gibson

I think that is what the AC_HEADER_STDBOOL already does - but that detects the gcc header, and the additional check needs to be for the clang header.

Unless you can convince clang to use the gcc headers?

Ahh, my bad :(

Signature · 1 line
viresh
#4 lore raw
Quoted 9 lines · Viresh Kumar
Quoted 5 lines · Kent Gibson

I think that is what the AC_HEADER_STDBOOL already does - but that detects the gcc header, and the additional check needs to be for the clang header.

Unless you can convince clang to use the gcc headers?

Ahh, my bad :(

On a relate note, how do you run clippy now?

When I tried cargo clippy I got an error about pkg-config not finding libgpiod. Fixed that by pointing PKG_CONFIG_PATH at my local libgpiod build.

But now I get:

--- stderr
wrapper.h:1:10: fatal error: 'gpiod.h' file not found
thread 'main' panicked at 'Unable to generate bindings: ClangDiagnostic("wrapper.h:1:10: fatal error: 'gpiod.h' file not found\n")', libgpiod-sys/build.rs:44:10

so I guess bindgen/clang needs to be pointed at the include directory, but not sure how to do that without emulating whatever make is doing.

Same goes for cargo build, come think of it - now you have to build using make.

How are you supposed to tell if your code is sub-par without clippy to tell you? Or, more generally, how does the development process for the rust bindings work now?

Cheers,
Kent.

#5 lore raw
Quoted 16 lines

On a relate note, how do you run clippy now?

When I tried cargo clippy I got an error about pkg-config not finding libgpiod. Fixed that by pointing PKG_CONFIG_PATH at my local libgpiod build.

But now I get:

--- stderr
wrapper.h:1:10: fatal error: 'gpiod.h' file not found
thread 'main' panicked at 'Unable to generate bindings: ClangDiagnostic("wrapper.h:1:10: fatal error: 'gpiod.h' file not found\n")', libgpiod-sys/build.rs:44:10

so I guess bindgen/clang needs to be pointed at the include directory, but not sure how to do that without emulating whatever make is doing.

Quoted 6 lines

Same goes for cargo build, come think of it - now you have to build using make.

How are you supposed to tell if your code is sub-par without clippy to tell you? Or, more generally, how does the development process for the rust bindings work now?

Setting PKG_CONFIG_PATH will only work if you point it at the install folder of libgpiod. If you do not want to install, you will need to set something like this (taken from the Makefile):

    SYSTEM_DEPS_LIBGPIOD_NO_PKG_CONFIG=1 \
    SYSTEM_DEPS_LIBGPIOD_SEARCH_NATIVE="${PWD}/../../../lib/.libs/" \
    SYSTEM_DEPS_LIBGPIOD_LIB=gpiod \
    SYSTEM_DEPS_LIBGPIOD_INCLUDE="${PWD}/../../../include/"  \
    cargo clippy

See https://lore.kernel.org/r/[email protected]/
on why it had to become a little bit ugly for rust bindings hackers.

Maybe we should put that example back to the README.md (or into the top- level README?)

- Erik

#6 lore raw
Quoted 19 lines · Erik Schilling
Quoted 19 lines

On a relate note, how do you run clippy now?

When I tried cargo clippy I got an error about pkg-config not finding libgpiod. Fixed that by pointing PKG_CONFIG_PATH at my local libgpiod build.

But now I get:

--- stderr
wrapper.h:1:10: fatal error: 'gpiod.h' file not found
thread 'main' panicked at 'Unable to generate bindings: ClangDiagnostic("wrapper.h:1:10: fatal error: 'gpiod.h' file not found\n")', libgpiod-sys/build.rs:44:10

so I guess bindgen/clang needs to be pointed at the include directory, but not sure how to do that without emulating whatever make is doing.

Same goes for cargo build, come think of it - now you have to build using make.

Quoted 6 lines
Quoted 3 lines

How are you supposed to tell if your code is sub-par without clippy to tell you? Or, more generally, how does the development process for the rust bindings work now?

Setting PKG_CONFIG_PATH will only work if you point it at the install folder of libgpiod.

Correct - that is exactly what I did.

Quoted 1 line

If you do not want to install, you will need to set

Yeah, I don't install on my dev machine - I deploy to separate machines for testing. For dev I just want to be able to use the same workflow I would use for a general rust project, so cargo XXX, and purely in the code tree. At least that is what I was doing previously.

Quoted 8 lines

something like this (taken from the Makefile):

    SYSTEM_DEPS_LIBGPIOD_NO_PKG_CONFIG=1 \
    SYSTEM_DEPS_LIBGPIOD_SEARCH_NATIVE="${PWD}/../../../lib/.libs/" \
    SYSTEM_DEPS_LIBGPIOD_LIB=gpiod \
    SYSTEM_DEPS_LIBGPIOD_INCLUDE="${PWD}/../../../include/"  \
    cargo clippy

Something like that?
That works for me when called from the rust/xxx sub-directories - I assume that is the correct level for the relative paths to work.

Quoted 3 lines

See https://lore.kernel.org/r/[email protected]/
on why it had to become a little bit ugly for rust bindings hackers.

I understand why you might be changing things to be able to package the crates, but in an ideal world that wouldn't impact normal workflow. Or it would be simple to switch.

Quoted 3 lines

Maybe we should put that example back to the README.md (or into the top- level README?)

Sounds like a plan to me. I would go with the rust specific README. Or add a file that can be sourced to setup the build environment to get cargo working from the command line.

Cheers,
Kent.

#7 lore raw
Quoted 11 lines
Quoted 2 lines

Setting PKG_CONFIG_PATH will only work if you point it at the install folder of libgpiod.

Correct - that is exactly what I did.

Quoted 1 line

If you do not want to install, you will need to set

Yeah, I don't install on my dev machine - I deploy to separate machines for testing. For dev I just want to be able to use the same workflow I would use for a general rust project, so cargo XXX, and purely in the code tree. At least that is what I was doing previously.

I agree that there is _some_ friction, but I did not come up with a way to preserve the old behavior without the risk of being confusing for consumers of the lib (or even people attempting to compile things where libgpiod-sys is just a transitive dependency).

The current solution mostly resembles how most of the Rust bindings that I know work. But I acknowledge that those bindings are usually developed in repositories separate from the underlying lib. Are there good examples how other libs are solving this problem?

Quoted 6 lines
Quoted 2 lines

See https://lore.kernel.org/r/[email protected]/
on why it had to become a little bit ugly for rust bindings hackers.

I understand why you might be changing things to be able to package the crates, but in an ideal world that wouldn't impact normal workflow. Or it would be simple to switch.

I fear the ideal world where there is no impact may be hard to achieve. When building with make, we _know_ that the C lib is also built, but when building from cargo, there is no good way (that I know of) to differ between a build that just happens because someone is building from crates.io or a developer invoking cargo sub-commands. Ideally, a build from local source should also show identical behavior compared to a build from the registry.

Also, we will (at least in the future) need an easy way to build against different versions of the C lib. For me the easiest way seems to be to install different libgpiod versions to some non-system path and then use PKG_CONFIG_PATH to switch... That just allows us to use standard mechanisms without requiring to reinvent any wheels.

Quoted 7 lines
Quoted 3 lines

Maybe we should put that example back to the README.md (or into the top- level README?)

Sounds like a plan to me. I would go with the rust specific README. Or add a file that can be sourced to setup the build environment to get cargo working from the command line.

I started with the README. Sent as part of my series of last crates.io publishing tweaks:

https://lore.kernel.org/r/[email protected]

- Erik