Skip to content

[SR-3819] ICU often needs -ldl, even if linked statically #46404

Closed
@weissi

Description

@weissi
Previous ID SR-3819
Radar None
Original Reporter @weissi
Type Bug

Attachment: Download

Additional Detail from JIRA
Votes 6
Component/s Compiler
Labels Bug, Driver, Linux
Assignee None
Priority Medium

md5: 52de48fd6048234a1c72d6a42d29e78d

Issue Description:

If ICU isn't compiled with --disable-dyload it'll need -ldl to be linked. That's a problem in Swift when producing a static executable:

$ echo 'print("Hello World")' > test.swift && swiftc -static-executable test.swift
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/libicuuc.a(putil.ao):function uprv_dl_open_55: error: undefined reference to 'dlopen'
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/libicuuc.a(putil.ao):function uprv_dlsym_func_55: error: undefined reference to 'dlsym'
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/libicuuc.a(putil.ao):function uprv_dl_close_55: error: undefined reference to 'dlclose'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)

My Swift compiler is version

Swift version 3.1-dev (LLVM 5c165fb715, Clang e540ba0c30, Swift 3d3fdecbb4)
Target: x86_64-unknown-linux-gnu

which is master of 2017-02-01.

I already verified that it can be fixed the following way:

/tmp/jw-swift/usr/bin/swiftc -o main.o -c main.swift
"/usr/bin/ld.gold" "-z" "relro" "--hash-style=gnu" "--build-id" "-m" "elf_x86_64" "-static" "-o" "test" "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crt1.o" "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crti.o" "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/crtbeginT.o" "-L/tmp/jw-swift/usr/lib/swift_static/linux" "-L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0" "-L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu" "-L/lib/x86_64-linux-gnu" "-L/lib/../lib64" "-L/usr/lib/x86_64-linux-gnu" "-L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../.." "-L/usr/lib/llvm-3.8/bin/../lib" "-L/lib" "-L/usr/lib" "/tmp/jw-swift/usr/lib/swift_static/linux/x86_64/swift_begin.o" "main.o" "-ldl" "-lswiftCore" "-lswiftImageInspectionStatic" "--defsym=__import_pthread_self=pthread_self" "--defsym=__import_pthread_once=pthread_once" "--defsym=__import_pthread_key_create=pthread_key_create" "-lpthread" "-licui18n" "-licuuc" "-licudata" "-lswiftCore" "-lswiftSwiftOnoneSupport" "/tmp/jw-swift/usr/lib/swift_static/linux/x86_64/swift_end.o" "-lstdc++" "-lm" "--start-group" "-lgcc" "-lgcc_eh" "-lc" -ldl "--end-group" "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/crtend.o" "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crtn.o"

the only difference between this and the standard invocation is the -ldl inbetween the --start-group and --end-group linker flags.

I'd be happy to fix this but I'm unsure where exactly to do that. Any pointers?

Notes

$ icu-config --ldflags
 -L/usr/lib/x86_64-linux-gnu -licui18n -licuuc -licudata  
$ icu-config --ldflags-system
-ldl -lm   
  • I'm running Ubuntu 16.04

  • it's not enough to just pass -ldl to swiftc (or -Xlinker -ldl)

  • the -ldl NEEDS to be in between ld.gold's --start-group and --end-group and I'm unsure how to get it there

  • the addition of -ldl should obviously only happen if ICU is compiled without --disable-dyload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    LinuxPlatform: LinuxbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselflegacy driverArea → compiler: the integrated C++ legacy driver. Succeeded by the swift-driver projectlinker errorunexpected errorBug: Unexpected error

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions