Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glibc undefined symbol: fcntl64 when using zig cc as a drop-in compiler #5882

Closed
creationix opened this issue Jul 16, 2020 · 21 comments
Closed
Labels
bug Observed behavior contradicts documented or intended behavior os-linux zig cc Zig as a drop-in C compiler feature
Milestone

Comments

@creationix
Copy link

I'm trying to build a small test application with libuv embedded. I want to use zig cc because the caching system makes it much faster. The following command works for clang and gcc, but not zig cc.

zig cc -o main main.c libuv/src/fs-poll.c libuv/src/idna.c libuv/src/inet.c libuv/src/random.c libuv/src/strscpy.c libuv/src/threadpool.c libuv/src/timer.c libuv/src/uv-common.c libuv/src/uv-data-getter-setters.c libuv/src/version.c libuv/src/unix/async.c libuv/src/unix/core.c libuv/src/unix/dl.c libuv/src/unix/fs.c libuv/src/unix/getaddrinfo.c libuv/src/unix/getnameinfo.c libuv/src/unix/loop-watcher.c libuv/src/unix/loop.c libuv/src/unix/pipe.c libuv/src/unix/poll.c libuv/src/unix/process.c libuv/src/unix/random-devurandom.c libuv/src/unix/signal.c libuv/src/unix/stream.c libuv/src/unix/tcp.c libuv/src/unix/thread.c libuv/src/unix/tty.c libuv/src/unix/udp.c libuv/src/unix/proctitle.c libuv/src/unix/linux-core.c libuv/src/unix/linux-inotify.c libuv/src/unix/linux-syscalls.c libuv/src/unix/procfs-exepath.c libuv/src/unix/random-getrandom.c libuv/src/unix/random-sysctl-linux.c -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D_POSIX_C_SOURCE=200112 -Os -ldl -lrt  -Ilibuv/include -Ilibuv/src
Compile C Objects [36/36] random-sysctl-linux.c...lld: error: undefined symbol: fcntl64
>>> referenced by core.c
>>>               zig-cache/o/a98yrC-16nzaiLvm0YSsj7Kr64jgWlKyw30Ca_aTuY8lBx8HcWfjUWLmNzWOQ59K/core.o:(uv__nonblock_fcntl)
>>> referenced by core.c
>>>               zig-cache/o/a98yrC-16nzaiLvm0YSsj7Kr64jgWlKyw30Ca_aTuY8lBx8HcWfjUWLmNzWOQ59K/core.o:(uv__nonblock_fcntl)
>>> referenced by core.c
>>>               zig-cache/o/a98yrC-16nzaiLvm0YSsj7Kr64jgWlKyw30Ca_aTuY8lBx8HcWfjUWLmNzWOQ59K/core.o:(uv__cloexec_fcntl)
>>> referenced by core.c
>>>               zig-cache/o/a98yrC-16nzaiLvm0YSsj7Kr64jgWlKyw30Ca_aTuY8lBx8HcWfjUWLmNzWOQ59K/core.o:(uv__cloexec_fcntl)
>>> referenced by pipe.c
>>>               zig-cache/o/Gp2nxP14BgUu9fMnuMMJ4gryoTCPAocIoqmgTAVdptPg5_FP1QjIdJRHfMpqm3ls/pipe.o:(uv_pipe_open)
>>> referenced by process.c
>>>               zig-cache/o/Z2n-GR8LD-1fXu4uIs37LmdvcK0K1mfCZ4iNwE1idOtrGfUhw6eXoJ8i5oMbsgSg/process.o:(uv__process_child_init)
>>> did you mean: fcntl64
>>> defined in: /home/tim/.cache/zig/stage1/h/pVSItZEIxIXx_ZQQwt9SLNNbPH8xxZp1plbirUK6SOmyZ4FTf2EOP08onozfGP03/libc.so.6.0.0

Is there something special I need to pass in for this to build?

@creationix
Copy link
Author

In particular, I'm confused by lld: error: undefined symbol: fcntl64 and then did you mean: fcntl64

@andrewrk
Copy link
Member

Hmm that is indeed confusing. I think the next step towards troubleshooting this would be to hop into one of the LLVM chat rooms and ask LLD developers if they know why this could happen.

@andrewrk andrewrk added bug Observed behavior contradicts documented or intended behavior zig cc Zig as a drop-in C compiler feature labels Jul 16, 2020
@andrewrk andrewrk added this to the 0.8.0 milestone Jul 16, 2020
@andrewrk
Copy link
Member

One work around would be to try musl libc instead of glibc: -target native-native-musl

@squeek502
Copy link
Collaborator

This is the same problem I was running into here luvit/luvi#231 (comment):

Now I'm running into a problem with mismatched glibc versions (zig cc is compiling against a newer one than my system glibc; specifically it's trying to use fnctl64 which my glibc doesn't have). Zig has the ability to target specific glibc versions (e.g. -target native-native-gnu.2.23) but I'm not sure it affects zig cc.

and luvit/luvi#231 (comment).

Targeting musl should work unless you need dynamic loading (luvit/luvi#231 (comment)).

@creationix
Copy link
Author

@squeek502 yep, you're right that I missed your comment in the luvi repo. This is the exact same issue! I guess it's something in libuv that's causing the problem since I don't have luajit at all in this project.

I tried -target native-native-musl and I get the same error though. Let me push my code and see if I'm doing it right...

@marler8997
Copy link
Contributor

Just a thought, maybe fcntl64 is versioned? I was recently working with libefivar and they version their symbols using -Wl,--version-script=FILE, not sure exactly how versioning symbols works but could be a potential explanation for this error.

@daurnimator
Copy link
Contributor

As in #6036, could you try using a newer glibc version as part of your target?

@aniljava
Copy link

aniljava commented Oct 1, 2020

Using c library triggers this errors, either as built.zig or in build-exe

/ws/projects/zig/sqlite :: # zig build
Build Dependencies... lld: error: /usr/lib/libsqlite3.so: undefined reference to fcntl64

/ws/projects/zig/sqlite :: # ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9) 2.31

exe.linkSystemLibrary("c");

/ws/projects/zig/sqlite :: # zig build-exe src/main.zig  -lsqlite3 -lc
Build Dependencies... lld: error: /usr/lib/libsqlite3.so: undefined reference to fcntl64

main.zig

const std = @import("std");
const sqlite = @cImport(@cInclude("sqlite3.h"));

pub fn main() anyerror!void {
    var db: ?*sqlite.sqlite3 = undefined;
    
}

addition to init-exe generated build.zig

const exe = b.addExecutable("sqlite", "src/main.zig");

exe.linkSystemLibrary("c");
exe.linkSystemLibrary("sqlite3");

@zhaozg
Copy link
Contributor

zhaozg commented Nov 28, 2020

cross build libuv for linux on macos, failed with

[100%] Linking C executable luvi
ld.lld: error: undefined symbol: fcntl64
>>> referenced by amalgamation.c
>>>               CMakeFiles/luvi.dir/custom/sqlitext/amalgamation.c.o:(aSyscall)
>>> referenced by core.c
>>>               core.c.o:(uv__nonblock_fcntl) in archive luv.dir/deps/libuv/libuv_a.a
>>> referenced by core.c
>>>               core.c.o:(uv__nonblock_fcntl) in archive luv.dir/deps/libuv/libuv_a.a
>>> referenced 5 more times
>>> did you mean: fcntl64@GLIBC_2.28
>>> defined in: /Users/zhaozg/.cache/zig/o/2723a939ae2a5ffa91d29e2389d18ffc/libc.so.6
error: LLDReportedFailure
make[6]: *** [luvi] Error 1
make[5]: *** [CMakeFiles/luvi.dir/all] Error 2
make[4]: *** [all] Error 2
make[3]: *** [luvi-prefix/src/luvi-stamp/luvi-build] Error 2
make[2]: *** [CMakeFiles/luvi.dir/all] Error 2
make[1]: *** [all] Error 2
make: *** [luvi] Error 2

@zhaozg
Copy link
Contributor

zhaozg commented Dec 21, 2020

After read how-to-force-linkage-to-older-libc-fcntl-instead-of-fcntl64, I found an alternative way to build libuv with zig cc.

make a fcntl.map file

GLIBC_2.2.5 {
   fcntl;
};

And update luv/deps/libuv/src/unix/internal.h, and add a line asm (".symver fcntl64, fcntl@GLIBC_2.2.5"); before #endif /* UV_UNIX_INTERNAL_H_ */

use CC="zig cc -target x86_64-linux-gnu.2.17 -Wl,--version-script,path_of_fcntl.map" or "CC="zig cc -target aarch64-linux-gnu.2.17 -Wl,--version-script,path_of_fcntl.map"` to build libuv.

If x86_64-linux-gnu version below 2.17, maybe need more glibc api map, and I have not test that.

aarch64-linux-gnu not pass, because has no fcntl@GLIBC_2.2.5

@andrewrk andrewrk modified the milestones: 0.9.0, 0.8.1 Jan 20, 2021
@harryhaaren
Copy link

I've just bumped into this issue too, when compiling a native C project that extensively uses linker scripts for both visibility and versioning of symbols. A quick web search brings me to this issue, root cause was the undefined symbol: fcntl64, and suggests did you mean fcntl64@GLIB_2.28 (from the Zig musl build cache for this architecture).

@nektro
Copy link
Contributor

nektro commented May 22, 2021

can confirm this works if you add -target native-native-gnu.2.28 since fcntl64 was removed in glibc 2.29+

the main.c I used can be found here https://nikhilm.github.io/uvbook/basics.html#hello-world

$ zig version
0.8.0-dev.2591+4b69bd61e

$ uname -a
Linux Meghans-PBP 5.7.0-2-pinebookpro-arm64 #1 SMP PREEMPT Sat Apr 24 11:16:25 UTC 2021 aarch64 GNU/Linux

$ zigmod fetch
fetch: libuv: git: https://github.com/libuv/libuv

$ zig build -Dtarget=native-native-gnu.2.28

$ ./zig-out/bin/zig-libuv 
Now quitting.

edit:
zig.mod: https://clbin.com/ITDC2
build.zig: https://zigbin.io/0a334f

@motiejus
Copy link
Contributor

I have the same problem building sqlite3 amalgamation (3.36.0) for glibc 2.27 or older:

~/sqlite-amalgamation-3360000 $ zig cc --target=x86_64-linux-gnu.2.24 shell.c sqlite3.c -lpthread -ldl -lm -o sqlite.2.24
ld.lld: error: undefined symbol: fcntl64
>>> referenced by sqlite3.c
>>>               /home/motiejus/.cache/zig/o/b0eefed440b6d330af020a2a209205de/sqlite3.o:(aSyscall)
>>> did you mean: fcntl64@GLIBC_2.28
>>> defined in: /home/motiejus/.cache/zig/o/d7adab72898642dac7322f4d250dbd1a/libc.so.6

I cannot use older glibc version, because some production hosts run 2.24; I also cannot use the musl target, because some applications expose NSS symbols, thus must be linked against glibc (vaguely mentioned in https://eng.uber.com/hadoop-container-blog/).

Suggestion by @zhaozg (above) works! But ... is there a way to pass the asm line in a cflag directive instead of patching the source? In our case, sqlite is a dependency of a dependency, so even creating a patch is non-trivial to begin with, let alone maintain it during upgrades.

@motiejus
Copy link
Contributor

motiejus commented Jul 28, 2021

Following @zhaozg 's suggestion I found a slightly different approach that does not require changing the source files:

fcntl.h

#ifdef __ASSEMBLER__
.symver fcntl64, fcntl@GLIBC_2.2.5
#else
__asm__(".symver fcntl64, fcntl@GLIBC_2.2.5");
#endif

fcntl.map

GLIBC_2.2.5 {
   fcntl;
};

Compile command:

zig cc --target=x86_64-linux-gnu.2.24 shell.c sqlite3.c -lpthread -ldl -lm -Wl,--version-script,fcntl.map -include fcntl.h -o sqlite.2.24

@motiejus
Copy link
Contributor

I created #9485, which captures the problem with a very small C file.

@ratfactor
Copy link
Contributor

Also ran into this compiling https://github.com/vrischmann/zig-sqlite with the included SQLite 3.35.5 amalgam.

Both target suggestions above worked for me:

zig build run -Dtarget=native-native-musl

and

zig build -Dtarget=native-native-gnu.2.28

The error (might help someone else searching for this issue):

ld.lld: error: undefined symbol: fcntl64
>>> referenced by sqlite3.c
>>>               /home/dave/sync/proj/zig/shoebox6/zig-cache/o/4089122d496bd76a6e71a1ea3f7f7ee6/sqlite3.o:(aSyscall)
>>> did you mean: fcntl64@GLIBC_2.28
>>> defined in: /home/dave/.cache/zig/o/7fec61c5e150add8cc9a2bc712cfb30a/libc.so.6
error: LLDReportedFailure

@bradclawsie
Copy link

I stumbled upon this issue while trying to use the sqlite library. To add to the stopgap solutions provided above, here are some snippets for build.zig:

let's say there is a library state.zig written with sqlite support...to build:

const state_lib = b.addStaticLibrary("state", "lib/state.zig");
state_lib.setBuildMode(mode);
deps.addAllTo(state_lib);
state_lib.setTarget(std.build.Target{ .glibc_version = std.build.Target.SemVer{ .major = 2, .minor = 28 } });
state_lib.install();
var state_pkg = std.build.Pkg{ .name = state_lib.name, .path = std.build.FileSource{ .path = state_lib.root_src.?.path }, .dependencies = state_lib.packages.items };

and for tests:

var state_tests = b.addTest("lib/state.zig");
state_tests.setBuildMode(mode);
deps.addAllTo(state_tests);
state_tests.setTarget(std.build.Target{ .glibc_version = std.build.Target.SemVer{ .major = 2, .minor = 28 } });
state_tests.addPackage(state_pkg);

maybe these snippets help someone until a more automatic solution arrives...

@andrewrk andrewrk modified the milestones: 0.9.1, 0.9.0 Nov 20, 2021
@andrewrk andrewrk changed the title Problem building libuv with zig cc on linux. glibc undefined symbol: fcntl64 when using zig cc as a drop-in compiler Nov 24, 2021
andrewrk added a commit that referenced this issue Dec 13, 2021
This commit upgrades glibc shared library stub-creating code to use the
new abilists file which is generated by the new glibc-abi-tool project:
https://github.com/ziglang/glibc-abi-tool/

The abilists file is different in these ways:
 * It additionally encodes whether a symbol is a function or an object,
   and if it is an object, it additionally encodes the size in bytes.
 * It additionally encodes migrations of symbols from one library to
   another between glibc versions.
 * It is binary data instead of ascii.
 * It is one file instead of three.
 * It is 165 KB instead of 200 KB.

This solves a handful of bugs.

Fixes #5882
Fixes #7667
Fixes #8714
Fixes #8896
@andrewrk
Copy link
Member

Closing as a duplicate of #9485 since that one has a minimal reproduction test case.

@motiejus
Copy link
Contributor

Note to followers of this issue: fcntl64 and a few more functions got resolved in #15101. Try compiling your stuff now. :)

@chee-z1
Copy link

chee-z1 commented Nov 4, 2023

I had the same problem using raylib.

"C:\Program Files\zig\zig.exe" run C:/Users/userName/IdeaProjects/new_/main.zig
error: lld-link: undefined symbol: InitWindow
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:18
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: SetTargetFPS
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:19
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: CloseWindow
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:20
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: WindowShouldClose
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:21
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: BeginDrawing
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:22
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: ClearBackground
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:24
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: DrawText
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:25
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)
error: lld-link: undefined symbol: EndDrawing
    note: referenced by C:\Users\userName\IdeaProjects\new_\main.zig:23
    note:               C:\Users\userName\AppData\Local\zig\o\f59599752f0cead73359b7fdc6eb46c9\main.exe.obj:(main.main)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior os-linux zig cc Zig as a drop-in C compiler feature
Projects
None yet
Development

No branches or pull requests