Skip to content

Failed to include cmsis_gcc.h because c-translation puts extern variables outside of inline function. #19687

@Vitmark97

Description

@Vitmark97

Zig Version

0.12.0-dev.3667+77abd3a96

Steps to Reproduce and Observed Behavior

1. Source files

// problematic.h
static inline int problematic_func(void) {
  typedef int test_type_t;
  
  extern const test_type_t problematic_variable_1;
  extern const test_type_t problematic_variable_2;
  return problematic_variable_1 + problematic_variable_2;
}
// mainc.c
#include <stdio.h>
#include "problematic.h"

const int problematic_variable_1 = 10;
const int problematic_variable_2 = 35;

int main() {
  int result = problematic_func();
  printf("Result: %d\n", result);
  return 0;
}
// main.zig
const std = @import("std");
const problematic = @cImport({
    @cInclude("problematic.h");
});

export const problematic_variable_1: c_int = 10;
export const problematic_variable_2: c_int = 35;

pub fn main() void {
    const result = problematic.problematic_func();
    std.debug.print("Result: {}\n", .{result});
}

2. Try to compile C code

zig cc mainc.c -o mainc
./mainc

Prints Result: 45

3. Try to compile zig code

zig build-exe -lc -I. main.zig

Results in error:

.../cimport.zig:57:38: error: use of undeclared identifier 'test_type_t'
extern const problematic_variable_1: test_type_t;
                                     ^~~~~~~~~~~
.../cimport.zig:58:38: error: use of undeclared identifier 'test_type_t'
extern const problematic_variable_2: test_type_t;
                                     ^~~~~~~~~~~
main.zig:2:21: error: C import failed: AnalysisFail
const problematic = @cImport({

Generated zig code:

// cimport.zig
extern const problematic_variable_1: test_type_t;
extern const problematic_variable_2: test_type_t;
pub fn problematic_func() callconv(.C) c_int {
    const test_type_t = c_int;
    _ = &test_type_t;
    return problematic_variable_1 + problematic_variable_2;
}

4. Putting the typedef int test_type_t outside of the inline function

zig build-exe -lc -I. main.zig
./main

Prints Result: 45

Context

I've started to experiment with using zig on STM32G431 with STM32 HAL and CMSIS libraries and I'm getting a C import failed error because of __cmsis_start(void) function in cmsis_gcc.h.

https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS/Core/Include/cmsis_gcc.h#L137

The function contains type definitions for extern variables inside of it. When zig translates this code it leaves the type definitions inside the function but puts the extern variables before the function. This results in error where the type is not known at the point of extern declaration.

For now I can get around this issue without having to modify cmsis_gcc.h by defining @cDefine("__PROGRAM_START", ""); before including any STM32 HAL headers.

Expected Behavior

Successful compilation of zig code that includes inline C function with extern variables inside of it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviortranslate-cC to Zig source translation feature (@cImport)

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions