Translate C lib using <immintrin.h>

Hi all,
Trying to learn zig for a while now, which is mostly a pleasant experience.
However the build system is something i find hard to coerce to do what i want.
Which is becoming more of an issue with cimport moving to translate-c.

I am trying to build a zig program that is using a very simple C library and includes the <immintrin.h> header.

Here i’ve made a modified version of the translate-c example for using a static library and changed the add.h function to include the <immintrin.h> header and some function using it:

add.h:
#ifndef FOO_ADD_H
#define FOO_ADD_H

#include <immintrin.h>

// Add `x` to `y`, and return the result.
int foo_add(int x, int y);

__m256i foo_add4(__m256i x, __m256i y);

#endif

Building this results in the error: ‘immintrin.h’ not found

❯ zig build 
test 
└─ run exe main 
   └─ compile exe main Debug native 
      └─ translate-c generated failure 
.zig-cache/o/a51102692b8c87bef79a4bbf75c8b622/foo/add.h:4:10: fatal error: 'immintrin.h' not found 
#include <immintrin.h> 
         ^ 
error: FatalError 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Diagnostics.zig:495:39: 0x15cfd6d in addWithLocation (aro.zig) 
    if (copy.kind == .@"fatal error") return error.FatalError; 
                                      ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:1088:5: 0x192ee73 in fatalNotFound (aro.zig) 
    try pp.diagnostics.addWithLocation(pp.comp, .{ 
    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:3736:9: 0x19332c5 in findIncludeSource (aro.zig) 
        return pp.fatalNotFound(filename_tok, filename); 
        ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:3536:21: 0x1933783 in include (aro.zig) 
        else => |e| return e, 
                    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:835:25: 0x18ba4ae in preprocessExtra (aro.zig) 
                        try pp.include(&tokenizer, .first); 
                        ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:3566:21: 0x1934205 in include (aro.zig) 
        else => |e| return e, 
                    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:835:25: 0x18ba4ae in preprocessExtra (aro.zig) 
                        try pp.include(&tokenizer, .first); 
                        ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:508:21: 0x18b44ff in preprocess (aro.zig) 
        else => |e| return e, 
                    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:498:17: 0x18b0629 in preprocessSources (aro.zig) 
    const eof = try pp.preprocess(sources.main); 
                ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/src/main.zig:423:5: 0x1311460 in translate (main.zig) 
    try pp.preprocessSources(.{ 
    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/src/main.zig:45:21: 0x1316a70 in main (main.zig) 
        else => |e| return e, 
                    ^ 
error: process exited with code 1 
failed command: ./.zig-cache/o/7f001d8970c784d694afa07e6700a2d1/translate-c -o=./.zig-cache/tmp/9266cd6a0cf9d133/generated.zig -lc --zig-lib=/home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig -fmodule-libs -- ./.zig-cache/o/1f7d9a798faf1f4c989ab9
1fcab40298/c.h -MD -MV -MF ./.zig-cache/tmp/9266cd6a0cf9d133/deps.d -w -resource-dir /home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D -I ./.zig-cache/o/a51102692b8
c87bef79a4bbf75c8b622

Note that this error is due to translate-c of the header: If the <immintrin.h> header is only included in the add.c file and the function is changed to not take/return __m256 vars the build succeeds. So clang is finding the header just fine.

Also running zig translate-c on the commandline gives me:

❯ zig translate-c  -lc add.c   > add.zig error: translation failure /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4657:19: error: use of unknown builtin ‘__builtin_elementwise_fshr’   return (__m512i)__builtin_elementwise_fshr((__v16su)__A,(__v16su)__A, (__v16su)__B);                   ^ /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4657:19: error: invalid conversion between vector type ‘__m512i’ (vector of 8 ‘long long’ values) and integer type ‘int’ of different size   return (__m512i)__builtin_elementwise_fshr((__v16su)__A,(__v16su)__A, (__v16su)__B);                   ^ /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4657:19: note: previous definition is here   return (__m512i)__builtin_elementwise_fshr((__v16su)__A,(__v16su)__A, (__v16su)__B);                   ^ /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4679:19: error: invalid conversion between vector type ‘__m512i’ (vector of 8 ‘long long’ values) and integer type ‘int’ of different size   return (__m512i)__builtin_elementwise_fshr((__v8du)__A, (__v8du)__A, (__v8du)__B);                   ^ /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4769:19: error: use of unknown builtin ‘__builtin_elementwise_fshl’   return (__m512i)__builtin_elementwise_fshl((__v16su)__A, (__v16su)__A, (__v16su)__B);                   ^ /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4769:19: error: invalid conversion between vector type ‘__m512i’ (vector of 8 ‘long long’ values) and integer type ‘int’ of different size   return (__m512i)__builtin_elementwise_fshl((__v16su)__A, (__v16su)__A, (__v16su)__B);                   ^ /home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig/include/avx512fintrin.h:4769:19: note: previous definition is here   return (__m512i)__builtin_elementwise_fshl((__v16su)__A, (__v16su)__A, (__v16su)__B);                   ^ (and more)
        else => |e| return e, 
                    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:835:25: 0x18ba4ae in preprocessExtra (aro.zig) 
                        try pp.include(&tokenizer, .first); 
                        ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:3566:21: 0x1934205 in include (aro.zig) 
        else => |e| return e, 
                    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:835:25: 0x18ba4ae in preprocessExtra (aro.zig) 
                        try pp.include(&tokenizer, .first); 
                        ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:508:21: 0x18b44ff in preprocess (aro.zig) 
        else => |e| return e, 
                    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D/src/aro/Preprocessor.zig:498:17: 0x18b0629 in preprocessSources (aro.zig) 
    const eof = try pp.preprocess(sources.main); 
                ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/src/main.zig:423:5: 0x1311460 in translate (main.zig) 
    try pp.preprocessSources(.{ 
    ^ 
/home/otto/Data/Documents/Programming/git/trans2/translate-c/src/main.zig:45:21: 0x1316a70 in main (main.zig) 
        else => |e| return e, 
                    ^ 
error: process exited with code 1 
failed command: ./.zig-cache/o/7f001d8970c784d694afa07e6700a2d1/translate-c -o=./.zig-cache/tmp/9266cd6a0cf9d133/generated.zig -lc --zig-lib=/home/otto/Data/Documents/Programming/git/zig/build/stage3/lib/zig -fmodule-libs -- ./.zig-cache/o/1f7d9a798faf1f4c989ab9
1fcab40298/c.h -MD -MV -MF ./.zig-cache/tmp/9266cd6a0cf9d133/deps.d -w -resource-dir /home/otto/Data/Documents/Programming/git/trans2/translate-c/examples/use_static_lib/zig-pkg/aro-0.0.0-JSD1QqO_OABFwQ7sIbrkG_Es077a3egrqA28ontD2e_D -I ./.zig-cache/o/a51102692b8
c87bef79a4bbf75c8b622

Which does find the header, but has some problem with avx512 headers. Not sure what exactly the error is, but its not really a suprise since my system only has avx2.

Adding -mcpu=native still gives the errors on avx512 headers.

Probably i just need to add some includepath in the build script to point it to the location where it can find the header. However i have no idea how to do that. Besides it seems stange to have to do that as the build of the c-lib by clang succeeds without it just as the commandline translate.

The following is not picked up by the ‘Translator’:

// Prepare the `translate-c` dependency.
const translate_c = b.dependency("translate_c", .{});

// Build the C library. In reality this would probably be done via the package manager.
const libfoo = buildLibfoo(b, target, optimize);

// Create a `Translator` for C source code which `#include`s the needed headers.
// If necessary, it could also include different headers, define macros, etc.
const trans_libfoo: Translator = .init(translate_c, .{
    .c_source_file = b.addWriteFiles().add("c.h",
        \\#include <foo/add.h>
        \\#include <foo/print.h>
    ),
    .target = target,
    .optimize = optimize,
});
trans_libfoo.mod.addIncludePath(.{ .cwd_relative = "/usr/local/lib/clang/22/include" });

Any suggestions how to get this to work?

I may be wrong but I am pretty sure that the c_source_file option should point to the actual c file with the implementation rather than the c.h header.

I’m not sure but I also don’t think you need the full translate-c package for this and could use just the built-in addTranslateC methods. I had a question about it a few days ago, it might help you: Error in Zig file Generated from TranslateC

Sorry I couldn’t be more helpful.

This looks like an arocc missing feature. Zig 0.16.0 switched to using arocc for translating c files. My guess is that this builtin is not handled by arocc. Arocc has been focused on gcc compatibility, as far as I can tell, and is missing a lot of Clang stuff. It would be worth filing a report with a minimal repo (like your add.h file).