rust-lang / rust-lang/rust-bindgen

Missing constants on macOS vs Linux

Open
#2,110 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

I get some #define constants from a C header missing in the generated bindings when building on Linux vs. macOS.

The constants in question, all starting with the TA_INTEGER prefix, are not behind any conditionals #if in the header but use other constants. See C Header section below.

Namely they use INT_MIN/INT_MAX which come from limits.h. The C lib I am wrapping builds fine and its code uses TA_INTEGER_MIN/TA_INTEGER_MAX/TA_INTEGER_DEFAULT; i.e. the constants from limits.h are 'seen' and used – on both platforms.

I am using Rust nighly and latest bindgen. Of note: clang is @ 5.0.1 on the Linux (CentOS) vs 12.0 on macOS.

Grepping on the bindings on macOS:

~/c/c/ta-lib-rs/tar/d/b/ta-lib-sys-9975acf6d6f5a59e
❯ rg TA_INTEGER_DEFAULT
out/bindings.rs
7:pub const TA_INTEGER_DEFAULT: i32 = -2147483648;

out/include/ta-lib/ta_defs.h
213:#define TA_INTEGER_DEFAULT (INT_MIN)

But on Linux:

~/c/c/ta-lib-rs/tar/d/b/ta-lib-sys-26bcdc06d91e3e82
❯ rg TA_INTEGER
out/include/ta-lib/ta_defs.h
213:#define TA_INTEGER_DEFAULT (INT_MIN)

If I run the above, grepping for TA_REAL instead, I get the same output on both platforms. I.e. constants starting with TA_REAL are there, constants starting with TA_INTEGER are missing on Linux.

It looks as if some stuff incoming from limits.h is just not recognized/omitted by bindgen which then leads to the TA_INTEGER prefixed constants missing in the generated binding. Just a guess ofc.

C Header

wrapper.h.

The actual offending header is this one, ta_defs.h, line 213 – #define TA_INTEGER_DEFAULT (INT_MIN).

/* min/max value for a TA_Integer */
#define TA_INTEGER_MIN (INT_MIN+1)
#define TA_INTEGER_MAX (INT_MAX)

/* min/max value for a TA_Real 
 *
 * Use fix value making sense in the
 * context of TA-Lib (avoid to use DBL_MIN
 * and DBL_MAX standard macro because they
 * are troublesome with some compiler).
 */
#define TA_REAL_MIN (-3e+37)
#define TA_REAL_MAX (3e+37)

/* A value outside of the min/max range 
 * indicates an undefined or default value.
 */
#define TA_INTEGER_DEFAULT (INT_MIN)
#define TA_REAL_DEFAULT    (-4e+37)
Bindgen Invocation
let bindings = bindgen::Builder::default()
         .header("wrapper.h")
         .clang_arg(format!("-I{}", out_path.join("include").display()))
         .allowlist_function("TA_.*")
         .allowlist_type("TA_.*")
         .allowlist_var("TA_.*")
         .generate()

This then leads to a bunch of:

error[E0425]: cannot find value `TA_INTEGER_DEFAULT` in crate `ta`
   --> ta-lib/src/macros.rs:170:29
    |
170 |                           ta::TA_INTEGER_DEFAULT
    |                               ^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `TA_REAL_DEFAULT`

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ta-lib-sys/wrapper.h and ta_defs.h around line 213, then inspect the bindgen invocation and compare generated bindings under the Linux and macOS clang versions described. Reproduce the allowlisted TA_INTEGER and TA_REAL constants, then verify that the TA_INTEGER constants are generated consistently and the Rust references compile.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.