zig icon indicating copy to clipboard operation
zig copied to clipboard

Way to set shared library filename

Open daurnimator opened this issue 6 years ago • 7 comments

When creating a shared library for use as a plugin in existing programs/languages, you often need to follow certain naming conventions, e.g. myprogram-plugin-b.so.

I can't seem to find a way to set the output filename from zig build-lib -dynamic. It seems to come out as libNAME.so.x.y.z where NAME can be set with --name and x/y/z can come from the --ver flags.

Possibly related to #2230

daurnimator avatar Apr 10 '19 09:04 daurnimator

I also need this feature.

https://github.com/ziglang/zig/issues/2230#issuecomment-655867321

waruqi avatar Jul 09 '20 02:07 waruqi

It would have been great if the core linux devs would have defined some proper rules for this but sadly it's the wild west. In CLang you just specify the target name,

HERE is the real challenge. I happen to be building a project with SQLite extensions. In particular there is note about loading dyn libs:

Note that different operating systems use different filename suffixes for their shared libraries. Windows use ".dll", Mac uses ".dylib", and most unixes other than mac use ".so". If you want to make your code portable, you can omit the suffix from the shared library filename and the appropriate suffix will be added automatically by the sqlite3_load_extension() interface.

This suggests to me that they are expecting the file to be absent of the version number. Hence the symlink.

rbucker avatar Sep 13 '20 13:09 rbucker

This suggests to me that they are expecting the file to be absent of the version number. Hence the symlink.

I think they are saying the file will have the platform-specific extension, and the sqlite3_load_extension function will automatically append the appropriate extension based on the detected operating system.

andrewrk avatar Oct 26 '20 01:10 andrewrk

This is now possible with -femit-bin=[filename] however the issue remains open until build.zig support lands.

andrewrk avatar Oct 26 '20 02:10 andrewrk

For what it's worth, I worked around this for my use-case of a PAM module with a custom build step in this commit: https://github.com/ifreund/rundird/commit/a2e13ba5b11726272ba6849da92f529203a5d65d

ifreund avatar Jul 26 '21 01:07 ifreund

I was doing:

 const lib = b.addSharedLibrary(.{
	.name = addon,
	.root_source_file = .{ .path = "src/lib/binding/node.zig" },
	.optimize = optimize,
	.target = target,
 });
 lib.emit_bin = .{ .emit_to = "build/lib/addon.node" };
 b.getInstallStep().dependOn(&lib.step);

and this previously "worked"[^1], though no longer works after #14647 (by running with --verbose I can see that the -femit-bin=build/lib/addon.node is there and the command succeeds, the file just doesnt get copied out of the zig-cache). I don't know if I was using it correctly beforehand or if I was holding it wrong and just got lucky, and I am aware that there are going to be changes to emit_to (#14971), but I'm curious if this regression was intended and what the correct way to set a shared library name via the build.zig is? (I'm currently just doing lib.install() and manually renaming the file in other code which is.... less than pleasant).

Details
kjs@scheibo(main)$ zig build -Dnode-headers=/Users/kjs/Code/include/node --verbose
/Users/kjs/Code/src/github.com/scheibo/zig/build/master/zig build-lib /Users/kjs/Code/src/github.com/scheibo/zigpkg/src/lib/binding/node.zig -lc -femit-bin=build/lib/zigpkg.node -fno-strip -fallow-shlib-undefined --cache-dir /Users/kjs/Code/src/github.com/scheibo/zigpkg/zig-cache --global-cache-dir /Users/kjs/.cache/zig --name zigpkg.node -dynamic -install_name @rpath/libzigpkg.node.dylib --mod zigpkg_options::/Users/kjs/Code/src/github.com/scheibo/zigpkg/zig-cache/options/QtBtQIzKPyfZuC40LT5ySYduiBbnI_SjoSS9ByFPwDIvooWZxlGT19Vxr_2_87kd --deps zigpkg_options -isystem /Users/kjs/Code/include/node --main-pkg-path /Users/kjs/Code/src/github.com/scheibo/zigpkg --enable-cache --listen=- 
kjs@scheibo(main)$ ls build
ls: build: No such file or directory
kjs@scheibo(main)$ tree zig-cache
zig-cache
├── h
│   ├── 214a532710a650196ecb3f843b6da067.txt
│   ├── aa6e3000386f1a1df251b9f3663f80fb.txt
│   ├── ec3a6fde0abf7687ee412ef519962281.txt
│   └── timestamp
├── o
│   ├── 4998256c861ad2abc0b241f3634576df
│   │   └── cimport.zig
│   ├── 4ca94f95ed5bc9c02d2403396621ca78
│   │   ├── cimport.h
│   │   └── cimport.h.d
│   ├── 5ab5fef32ca72e3a3fcc75cc1e9bfb11
│   │   └── builtin.zig
│   ├── 5f56dd2cae6ada7d11dd6475056e0c8c
│   │   ├── build
│   │   └── build.o
│   ├── 6893da36ba76199bd91f1af4460e3270
│   │   └── dependencies.zig
│   ├── 75467e3e9ecba447db2b4ddf5ac98a71
│   │   └── builtin.zig
│   └── baea46870b237fa185b5cab88f18804e
│       ├── zigpkg.node
│       └── zigpkg.node.o
├── options
│   └── QtBtQIzKPyfZuC40LT5ySYduiBbnI_SjoSS9ByFPwDIvooWZxlGT19Vxr_2_87kd
├── tmp
└── z
    ├── 05a7fbf4f7e00286a9884a9440c98f30
    ├── 0b0f898fd6945f36ab5b7d62155bfac2
    ├── 1a52e9e718f2fb9aee117bc60a74cbd8
    └── d85cc5f2905c8bf18b79f5d5f591aa6c

13 directories, 19 files

[^1]: I didn't like having to hardcode "build/lib", I couldn't find a way to get deduce what the install library prefix was and place the artifact there.

scheibo avatar Mar 19 '23 22:03 scheibo

For what it's worth, I worked around this for my use-case of a PAM module with a custom build step in this commit: ifreund/rundird@a2e13ba

~~I cleaned it up to be more generic and take *std.build.LibExeObjStep: https://gist.github.com/eNV25/a56a7169cdeeddef9b06257ec89360d9~~

Actually, you can do this already in zig 0.10.1:

const plugin_install = b.addInstallFileWithDir(plugin.getOutputSource(), .lib, "plugin.so");
plugin_install.step.dependOn(&plugin.step);
b.getInstallStep().dependOn(&plugin_install.step);

eNV25 avatar Aug 03 '23 13:08 eNV25