Static build and linux musl

I have hit another lack of my zig skill issue. I am not sure if what I’m trying to do even makes sense… but…

Here’s a summary of what I’m trying to do:

  • I’m targeting Linux operating system: x86_64-linux-musl
  • I’m trying to “compile once, run anywhere” (don’t want to install system/3rd party dependencies on other computers)
  • I need to make basic image manipulation: resize and access to raw RGB of pixels
  • I chose GraphicsMagick library for image manipulation

What I have and what works:

I have in the build.zig

...
    exe.linkLibC();
    exe.linkSystemLibrary("GraphicsMagick");
...

Dynamic building on default target works just fine with chosen optimization level, for example:

zig build -Doptimize=ReleaseFast

However, if I set the target to x86_64-linux-musl, I get an error that library cannot be found:

> zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux-musl
install
└─ install zixel
   └─ zig build-exe zixel ReleaseFast x86_64-linux-musl failure
error: error: unable to find dynamic system library 'GraphicsMagick' using strategy 'paths_first'. searched paths: none

I’m not sure what zig expects me to do when I get this error.

PS.

> echo `GraphicsMagick-config --cppflags --ldflags --libs`
-I/usr/include/GraphicsMagick -L/usr/lib -Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -Wl,-z,relro -Wl,-z,now -lGraphicsMagick -ljbig -lwebp -lwebpmux -lsharpyuv -lheif -llcms2 -ltiff -lfreetype -ljpeg -ljxl -ljxl_threads -lhwy -lbrotlidec -lbrotlienc -lstdc++ -lpng16 -lwmflite -lXext -lSM -lICE -lX11 -llzma -lbz2 -lxml2 -lz -lzstd -lm -lpthread -lgomp

Zig tries to find an archive for static linking.
Do you have a /usr/lib/libGraphicsMagick.a library?

Or can someone suggest me a (zig?) library that can read in at least PNG and JPG, and do resize… and could be made into static build?

Yep, it is there

:~$ ls /usr/lib/libGraphicsMagick.a
/usr/lib/libGraphicsMagick.a

Try:

  1. .linkage = .static, in the addExecutable options.
  2. linkSystemLibrary2 as:
    exe.linkSystemLibrary2("GraphicsMagick", .{
        .preferred_link_mode = .static,
    });

Still getting the same error message :frowning:

(But thanks about the exe.addSystemLibrary2, I didn’t know about it. But at least for the moment that didn’t fix the error message)

When you build for your native target (by omitting -target/-Dtarget or explicitly specifying native), Zig automatically adds host system paths like /usr/include or usr/lib to the include and library search paths.

When you build for a specific target like x86_64-linux-musl, Zig takes that to mean that you want to perform a “hermetic” (system-independent) build that doesn’t let system headers, libraries and other files from the host system leak into the build.

You could try explicitly adding a search path exe.root_module.addLibraryPath(.{ .cwd_relative = "/usr/lib" }) and/or specifying the use_pkg_config option in your call to linkSystemLibrary2.

However, I will note that if your goal is a system-independent “runs anywhere” build, statically linking with a system library might be problematic if GraphicsMagick was built with your particular host system in mind. So if you find that your program works on your system but not others’, you might want to instead compile GraphicsMagick yourself.

3 Likes

I gave up on GraphicsMagick in the end. In the end I chose zigimg, but it has limitations (not all common image formats, etc are supported).

Never the less, here it is

https://github.com/daredemo/zixel

A super simple sixel generator.