Trying to build a mysql test app

I am attempting to build a test app for accessing MySQL, but am unsure how zig works with dependencies and such.

My first attempt was to use zig build -lc -lmysql which failed because it couldn’t find MySQL in usr/includes/mysql.

I then decided to add mysql/mysql thinking maybe it wasn’t traversing into subdirectories and that got me past that error. zig build -lc -lmysql/mysql

However, it then appears to be looking for the binary files themselves, which are stored in /usr/local/mariadb-10.3.37-linux-systemd-x86_64/lib/libmysqld.so

The problem is, it doesn’t look in that folder and I’m unsure how to tell it to. I’ve tried a few things in the zon file but so far nothing has worked. Can anyone point me to the correct process to get this going?

Thanks,

Glenn

The following zig flags for C libraries are used only when calling zig build-exe, zig build-lib or zig cc:

Flags Description
-l (lowercase L) library to link to
-L libraries path
-I (uppercase i) include path

Also zig libc displays the system include and library paths used by zig.


To use libraries with zig build you need to specify them in your build.zig file.
The equivalent code for the -lmysql -lc flags is:

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

You can replace exe with any build artifact, for example lib or unit_tests.


Zig can use pkg-config; if pkg-config --libs mysql displays -lmysql then zig is going to find the installed locations.
Otherwise you may use addIncludePath and addLibraryPath.
See Build System Tricks for their usage.

1 Like

I feel like I am learning the c make files all over again. :slight_smile:

I added the lines just after the exe section but get the same results when I attempt to do a zig build. If I attempt a zig build-exe I get message that build-exe is not a valid command.

I apologize for being so ignorant on this. I am reading the links you sent but they’re not very helpful for someone that doesn’t already know what is going on.

thanks,

Glenn

zig build-exe src/main.zig worked. I didn’t realize I needed to give it the full path to the file. However, the options are still not fixing my problem.

I am still having trouble getting this mysql test app to compile. I have the so files located in /usr/local/mariadb-10.3.37-linux-systemd-x86_64/lib but nothing I do gets it to look into that folder.

Also, I am really confused about the .zon file. It has a path section there but adding these paths to it don’t seem to have any effect on what is going on. It seems odd that you could download source code from someone and you can’t get it to compile because your paths are different from theirs. Seems like it would end up being a mess.

These are the types of things I dealt with when I used to write C programs trying to find all the libraries and link files to get things to work. I don’t have these issues working with Go or Rust and just want to be sure I’m not doing something wrong.

Thanks,

Glenn

We are only going to be able to help you so much if you don’t include the source code.

It could be something where you are doing something incorrect in your build.zig file.

I encourage you to create a github repo and provide a link.

I’m assuming you are still failing to point build.zig to the correct location. Also I don’t want you to just be provided a solution if that is not what you are looking for, but there do appear to be similar projects already online. You could look to those for inspiration/help. (I see some zig projects using mysql after a short google search.)

Hope to hear from you again,

Sorry, I thought I had mentioned it above. I downloaded it from MySQL - Zig cookbook

At this point I am trying to figure out what needs to be added to the build files as well as what command I need to use to get it to compile. I am looking into whether or not I can get zig to replace go at some point and our system is based off of a REST/JSON server on top of MySQL databases. Specifically we use Mariadb and maybe that is part of my problem.

Thanks,

Glenn

Do you have a running mysql server and a mysql client that can connect to the server?

libmysqld is an embedded server, the code of the cookbook links to a mysql client.

Yes, I can connect to the mysql server but the error is happening before compile not when running the program. I’ve also located the so files and the header files but not sure how how to pass in the path to the so files. It acts like it can’t find them.

What is the zig command line that you tried and what is the error message that you get?
Include the build.zig, if you have one.

command: zig build-exe src/main.zig -lc -lmysql

I have also tried a number of other commands with no luck either.

build.zig

const std = @import("std");

// Although this function looks imperative, note that its job is to
// declaratively construct a build graph that will be executed by an external
// runner.
pub fn build(b: *std.Build) void {
    // Standard target options allows the person running `zig build` to choose
    // what target to build for. Here we do not override the defaults, which
    // means any target is allowed, and the default is native. Other options
    // for restricting supported target set are available.
    const target = b.standardTargetOptions(.{});

    // Standard optimization options allow the person running `zig build` to select
    // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
    // set a preferred release mode, allowing the user to decide how to optimize.
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addStaticLibrary(.{
        .name = "mysql",
        // In this case the main source file is merely a path, however, in more
        // complicated build scripts, this could be a generated file.
        .root_source_file = b.path("src/root.zig"),
        .target = target,
        .optimize = optimize,
    });

    // This declares intent for the library to be installed into the standard
    // location when the user invokes the "install" step (the default step when
    // running `zig build`).
    b.installArtifact(lib);

    const exe = b.addExecutable(.{
        .name = "mysql",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

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

    // This declares intent for the executable to be installed into the
    // standard location when the user invokes the "install" step (the default
    // step when running `zig build`).
    b.installArtifact(exe);

    // This *creates* a Run step in the build graph, to be executed when another
    // step is evaluated that depends on it. The next line below will establish
    // such a dependency.
    const run_cmd = b.addRunArtifact(exe);

    // By making the run step depend on the install step, it will be run from the
    // installation directory rather than directly from within the cache directory.
    // This is not necessary, however, if the application depends on other installed
    // files, this ensures they will be present and in the expected location.
    run_cmd.step.dependOn(b.getInstallStep());

    // This allows the user to pass arguments to the application in the build
    // command itself, like this: `zig build run -- arg1 arg2 etc`
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    // This creates a build step. It will be visible in the `zig build --help` menu,
    // and can be selected like this: `zig build run`
    // This will evaluate the `run` step rather than the default, which is "install".
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);

    // Creates a step for unit testing. This only builds the test executable
    // but does not run it.
    const lib_unit_tests = b.addTest(.{
        .root_source_file = b.path("src/root.zig"),
        .target = target,
        .optimize = optimize,
    });

    const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);

    const exe_unit_tests = b.addTest(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);

    // Similar to creating the run step earlier, this exposes a `test` step to
    // the `zig build --help` menu, providing a way for the user to request
    // running the unit tests.
    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&run_lib_unit_tests.step);
    test_step.dependOn(&run_exe_unit_tests.step);
}

build.zig.zon

.{
    .name = "mysql",
    .version = "0.0.1",
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
        "/usr/local/mariadb-10.3.37-linux-systemd-x86_64/lib",
        "/usr/includes/mysql",
    },
}

The error I am receiving:

error: unable to find dynamic system library 'mysql' using strategy 'paths_first'. searched paths:
  /usr/local/lib64/libmysql.so
  /usr/local/lib64/libmysql.a
  /usr/local/lib/libmysql.so
  /usr/local/lib/libmysql.a
  /usr/lib/x86_64-linux-gnu/libmysql.so
  /usr/lib/x86_64-linux-gnu/libmysql.a
  /lib64/libmysql.so
  /lib64/libmysql.a
  /lib/libmysql.so
  /lib/libmysql.a
  /usr/lib64/libmysql.so
  /usr/lib64/libmysql.a
  /usr/lib/libmysql.so
  /usr/lib/libmysql.a
  /lib/x86_64-linux-gnu/libmysql.so
  /lib/x86_64-linux-gnu/libmysql.a

I belive that zig build-exe doesn’t use your build.zig at all. You have to run zig build for that. From the error, it’s looking for either libmysql.so or libmysql.a in different known paths. Do you have those files on your system? I’m not sure if mariadb would use the same lib names as mysql.

These pathes don’t belong in your build.zig.zon, the pathes within build.zig.zon should all be relative pathes that are subdirectories of your project folder and they are for files that you ship with your project, if you wanted to ship certain build libraries as binary files with your project you would have to copy them to a subdirectory of your project, but it would be better to instead allow the user to specify the include path for the system library (or create a package that build the library from source).

If you use zig build-exe you can use -L/usr/local/mariadb-10.3.37-linux-systemd-x86_64/lib -L/usr/includes/mysql -l<name of lib without extension>

If you use build.zig and zig build you can use zig build --help to see this:

...
System Integration Options:
  --search-prefix [path]       Add a path to look for binaries, libraries, headers
...

I haven’t worked with zig and mysql in combination.
But you should try if this example works for you:

Note that build-exe command does not use build.zig. This is fine, until you have a working command line.

The library is “libmysqlclient.so” you need -lmysqlclient e.g.: zig build-exe src/main.zig -lc -lmysqlclient

If zig cannot find the library, provide an additional library path with -L/usr/local/..../lib (libmysqlclient.so or libmysqlclient.so.* or libmysqlclient.a must be present in the specified folder).

The next problem might be locating where is mysql.h that is included in the zig code. You can specify an additional include path using -I/usr/includes (mysql.h must be present in the specified folder).

The final, working, command line must be like:

zig build-exe src/main.zig -lc -lmysqlclient -L/path/to/lib -I/path/to/include

If mysql is located at system locations the following is enough:

zig build-exe src/main.zig -lc -lmysqlclient

Thank you,

1 Like