digitalmars.D.learn - Libc functions undefined when linking
- Ben Jones (43/43) Jan 04 2022 I have a somewhat unusual use case and I'm having trouble getting
- =?UTF-8?Q?Ali_=c3=87ehreli?= (3/6) Jan 04 2022 Ali
- Ben Jones (7/14) Jan 04 2022 Maybe it's a mac thing and that will work when I get to linux,
- Adam D Ruppe (10/11) Jan 04 2022 you might have better luck just telling clang to link it too
- Ben Jones (5/16) Jan 04 2022 Using clang seems to work better. It sounds like Apple basically
- Ben Jones (8/29) Jan 04 2022 All good, except now simpledisplay is segfaulting on
- Adam D Ruppe (6/8) Jan 04 2022 run it in the debugger; do a -g build and run it in gdb or lldb
- Ben Jones (21/29) Jan 04 2022 Crashes on `display = XOpenDisplay(displayName);` :
- Ben Jones (5/19) Jan 04 2022 Hmm, I get the same segfault on linux, I'm linking with these
- Adam D Ruppe (14/15) Jan 04 2022 That's null, meaning the library wasn't loaded.
- Ben Jones (7/22) Jan 04 2022 Ah, that was the issue. I had a linker error when I had a normal
- bachmeier (3/6) Jan 04 2022 Just for the record, while the official Fedora repos don't have
- Tejas (11/15) Jan 04 2022 I'm using Fedora 34
I have a somewhat unusual use case and I'm having trouble getting everything to link properly. I'm writing an assignment for a course I'm teaching and I've written the skeleton code in D, and students are going to implement one function in C, which my skeleton code will call. The tricky part is that the lab machines that the students will be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it). I plan to distribute compiled .o files for all the d modules, along with a static libphobos. The students can compile their C file, and then link everything together. I haven't tested it on the linux machines yet, but developing it on my mac, I'm getting undefined symbols for libc and pthread functions from libphobos: ``` "_thread_suspend", referenced from: __D4core6thread8osthread7suspendFNbNiCQBjQBhQBd6ThreadZb in libphobos2.a(osthread_8db_302.o) (maybe you meant: _thread_suspendAll) "_tmpfile", referenced from: __D3std5stdio4File7tmpfileFNfZSQBcQBbQy in libphobos2.a(stdio_d42_180.o) "_toupper", referenced from: __D2rt6config16rt_envvarsOptionFNbNiAyaMDFNbNiQkZQnZQq in libphobos2.a(config_94b_6c3.o) "_waitpid", referenced from: __D4core8internal2gc2os8wait_pidFNbNiibZEQBmQBkQBeQBe11ChildStatus in libphobos2.a(os_610_351.o) ``` So I think I need to specify that I want to explicitly include libc when I link it. `-lc` didn't seem to work. Anyone how the right way to do so? Here are the steps I'm doing. I'll compile all the D stuff myself, and distribute the .o files with my assignment, and they'll just be doing the C compilation and linking steps. ``` dmd -c -I=source -of=build/simpledisplay.o source/arsd/simpledisplay.d dmd -c -I=source -of=build/color.o source/arsd/color.d dmd -c -I=source -of=app.o source/app.d clang -c -o source/assignment1.o source/assignment1.c ld build/*.o -L. -lphobos2 -o build/executable ```
Jan 04 2022
On 1/4/22 10:13 AM, Ben Jones wrote:So I think I need to specify that I want to explicitly include libc when I link it. `-lc` didn't seem to work.Did you add -lc and -lpthread on the linker line?ld build/*.o -L. -lphobos2 -o build/executableAli
Jan 04 2022
On Tuesday, 4 January 2022 at 18:26:41 UTC, Ali Çehreli wrote:On 1/4/22 10:13 AM, Ben Jones wrote:Maybe it's a mac thing and that will work when I get to linux, but I did try that and ld couldn't find the lib: ``` ld: library not found for -lc ``` Same result for -lpthread, and for -pthread (no l)So I think I need to specify that I want to explicitlyinclude libc whenI link it. `-lc` didn't seem to work.Did you add -lc and -lpthread on the linker line?ld build/*.o -L. -lphobos2 -o build/executableAli
Jan 04 2022
On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:clang -c -o source/assignment1.o source/assignment1.cyou might have better luck just telling clang to link it too like since there's a bunch of default search paths and libs etc the compiler pass to the linker. otherwise if you do need to use the linker directly worth remembering the order of args matter too. you need to put the more derived dependencies first followed by more general ones at the end
Jan 04 2022
On Tuesday, 4 January 2022 at 18:37:25 UTC, Adam D Ruppe wrote:On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:Using clang seems to work better. It sounds like Apple basically hides system libraries since Big Sur, and I guess their clang knows the magic flags to pass to find them. Thanks!clang -c -o source/assignment1.o source/assignment1.cyou might have better luck just telling clang to link it too like since there's a bunch of default search paths and libs etc the compiler pass to the linker. otherwise if you do need to use the linker directly worth remembering the order of args matter too. you need to put the more derived dependencies first followed by more general ones at the end
Jan 04 2022
On Tuesday, 4 January 2022 at 18:45:37 UTC, Ben Jones wrote:On Tuesday, 4 January 2022 at 18:37:25 UTC, Adam D Ruppe wrote:All good, except now simpledisplay is segfaulting on XDisplayConnection.get again (you helped me before by specifying a DISPLAY environment variable, but that's not working now, with either :0 or the longer value set by xquartz when opening an xterm). I'm not sure how it can segfault since there are null checks in that method... maybe I should just head to the linux lab and stop fighting Apple.On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:Using clang seems to work better. It sounds like Apple basically hides system libraries since Big Sur, and I guess their clang knows the magic flags to pass to find them. Thanks!clang -c -o source/assignment1.o source/assignment1.cyou might have better luck just telling clang to link it too like since there's a bunch of default search paths and libs etc the compiler pass to the linker. otherwise if you do need to use the linker directly worth remembering the order of args matter too. you need to put the more derived dependencies first followed by more general ones at the end
Jan 04 2022
On Tuesday, 4 January 2022 at 19:10:25 UTC, Ben Jones wrote:All good, except now simpledisplay is segfaulting on XDisplayConnection.get againrun it in the debugger; do a -g build and run it in gdb or lldb and do check the exact line it is on. could be that the Xlib things didn't dynamically load. I thought I tested that but could have missed a spot and Apple has a bad habit of movign things so who knows.
Jan 04 2022
On Tuesday, 4 January 2022 at 19:14:04 UTC, Adam D Ruppe wrote:On Tuesday, 4 January 2022 at 19:10:25 UTC, Ben Jones wrote:Crashes on `display = XOpenDisplay(displayName);` : ``` EXC_BAD_ACCESS (code=1, address=0x0) gameboy`_D4arsd13simpledisplay18XDisplayConnection3getFZPSQBwQBu7Display at simpledisplay.d:12572 gameboy`_D4arsd13simpledisplay5Image4impl11createImageMFiibbZv(this 0x0000000101200000, enableAlpha=false, forcexshm=false, height=144, width=160) at simpledisplay.d:12678 gameboy`_D4arsd13simpledisplay5Image6__ctorMFiibbZCQBpQBnQBb(this 0x0000000101200000, enableAlpha=false, forcexshm=false, height=144, width=160) at simpledisplay.d:7065 ``` Which makes lots of sense because: "On a POSIX-conformant system, if the display_name is NULL, it defaults to the value of the DISPLAY environment variable." (https://www.x.org/releases/X11R7.5/doc/man/man3/XOpenDisplay.3.html) (/sarcasm) Explicitly calling setDisplayName before I try to use the display didn't make a difference, so maybe it's assignment to display that's causing the segfault? Not sure why that would cause a segfault eitherAll good, except now simpledisplay is segfaulting on XDisplayConnection.get againrun it in the debugger; do a -g build and run it in gdb or lldb and do check the exact line it is on. could be that the Xlib things didn't dynamically load. I thought I tested that but could have missed a spot and Apple has a bad habit of movign things so who knows.
Jan 04 2022
On Tuesday, 4 January 2022 at 20:28:00 UTC, Ben Jones wrote:On Tuesday, 4 January 2022 at 19:14:04 UTC, Adam D Ruppe wrote:Hmm, I get the same segfault on linux, I'm linking with these flags and I the only warnings I get are about unwinding offsets: `clang build/*.o -L. -lphobos2 -lX11 -ldl -lpthread -o build/gameboy`[...]Crashes on `display = XOpenDisplay(displayName);` : ``` EXC_BAD_ACCESS (code=1, address=0x0) gameboy`_D4arsd13simpledisplay18XDisplayConnection3getFZPSQBwQBu7Display at simpledisplay.d:12572 gameboy`_D4arsd13simpledisplay5Image4impl11createImageMFiibbZv(this 0x0000000101200000, enableAlpha=false, forcexshm=false, height=144, width=160) at simpledisplay.d:12678 gameboy`_D4arsd13simpledisplay5Image6__ctorMFiibbZCQBpQBnQBb(this 0x0000000101200000, enableAlpha=false, forcexshm=false, height=144, width=160) at simpledisplay.d:7065 [...]
Jan 04 2022
On Tuesday, 4 January 2022 at 21:22:26 UTC, Ben Jones wrote:That's null, meaning the library wasn't loaded. simpledisplay actually doesn't need -lX11 since it always dynamic loads the libraries. Normally it throws when this fails though instead of keeping null but that check is also initialized in a static constructor.... With your different build process though, do you still have a D main? If druntime is not fully initialized these libs won't load nor will it set the success flag. So that'd leave null. You can also quite possibly try to load it yourself: xlib.loadDynamicLibrary(); xext.loadDynamicLibrary(); in your main and see if it works. Then the variable to check is `if(!librariesSuccessfullyLoaded)` and see if it set it up.
Jan 04 2022
On Tuesday, 4 January 2022 at 21:34:46 UTC, Adam D Ruppe wrote:On Tuesday, 4 January 2022 at 21:22:26 UTC, Ben Jones wrote:Ah, that was the issue. I had a linker error when I had a normal d main, so I made main `extern(C)`. Looks like that wasn't actually necessary (I think maybe I had actually just put the .o with main in the wrong place so the symbol was missing). Reverting it to extern(D) fixed it on mac and linux. Thanks so much for the help!That's null, meaning the library wasn't loaded. simpledisplay actually doesn't need -lX11 since it always dynamic loads the libraries. Normally it throws when this fails though instead of keeping null but that check is also initialized in a static constructor.... With your different build process though, do you still have a D main? If druntime is not fully initialized these libs won't load nor will it set the success flag. So that'd leave null. You can also quite possibly try to load it yourself: xlib.loadDynamicLibrary(); xext.loadDynamicLibrary(); in your main and see if it works. Then the variable to check is `if(!librariesSuccessfullyLoaded)` and see if it set it up.
Jan 04 2022
On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it).Just for the record, while the official Fedora repos don't have dmd, they have both ldc and gdc.
Jan 04 2022
On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:The tricky part is that the lab machines that the students will be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it).I'm using Fedora 34 `sudo dnf install ldc` works and gives ldc version 1.25.0(based on dmd 2.095.1)(but you invoke via `ldc2` or `ldmd2`) name of rpm: Source : ldc-1.25.1-2.fc34.src.rpm `sudo dnf install gcc-gdc` also works(but it's not the recent one with the D frontend)(you don't even need to write `gdc <input_file>.d`, `gcc <infut_file>.d` also works.) name of rpm: Source : gcc-11.2.1-1.fc34.src.rpm
Jan 04 2022
On Wednesday, 5 January 2022 at 03:38:54 UTC, Tejas wrote:On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:good to know. What about dub?The tricky part is that the lab machines that the students will be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it).I'm using Fedora 34 `sudo dnf install ldc` works and gives ldc version 1.25.0(based on dmd 2.095.1)(but you invoke via `ldc2` or `ldmd2`) name of rpm: Source : ldc-1.25.1-2.fc34.src.rpm `sudo dnf install gcc-gdc` also works(but it's not the recent one with the D frontend)(you don't even need to write `gdc <input_file>.d`, `gcc <infut_file>.d` also works.) name of rpm: Source : gcc-11.2.1-1.fc34.src.rpm
Jan 05 2022
On Wednesday, 5 January 2022 at 16:14:02 UTC, Ben Jones wrote:On Wednesday, 5 January 2022 at 03:38:54 UTC, Tejas wrote:I can't say for sure, since I installed dmd from the website before installing the other two, but `dub` should be bundled with the other two as well Regardless, know that I didn't install dub seperately, it got installed with either the dmd rpm, or the LDC or GDC oneOn Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote:good to know. What about dub?The tricky part is that the lab machines that the students will be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it).I'm using Fedora 34 `sudo dnf install ldc` works and gives ldc version 1.25.0(based on dmd 2.095.1)(but you invoke via `ldc2` or `ldmd2`) name of rpm: Source : ldc-1.25.1-2.fc34.src.rpm `sudo dnf install gcc-gdc` also works(but it's not the recent one with the D frontend)(you don't even need to write `gdc <input_file>.d`, `gcc <infut_file>.d` also works.) name of rpm: Source : gcc-11.2.1-1.fc34.src.rpm
Jan 05 2022