[libcxx-dev] Is the C++ filesystem object file installed via LLVM's APT repository missing symbols?

Shoaib Meenai via libcxx-dev libcxx-dev at lists.llvm.org
Tue Apr 2 14:50:25 PDT 2019


Traditional Unix linkers only pull symbols from archives (static libraries) if an undefined reference to that symbol has already been seen by the time the static library is encountered on the command line. In other words, if libfoo.a defines foo, and bar.o has an undefined reference to foo, ordering them on the link line as bar.o libfoo.a will work, but libfoo.a bar.o won’t, since the undefined reference to foo appears after the static library defining it. This is the reason why static libraries are sometimes repeated on the command line or --start-group --end-group exist.

This is specific to traditional Unix linkers. LLD for ELF chooses is agnostic to the order of libraries; see “Efficient archive file handling” on http://lld.llvm.org/NewLLD.html. ld64 and Microsoft’s linker are also agnostic to the ordering (though Microsoft’s linker has its own peculiarities related to library symbol lookup, which again aren’t emulated by LLD for COFF; see https://docs.microsoft.com/en-us/cpp/build/reference/link-input-files?view=vs-2019, specifically “Libraries are searched in command line order as well, with the following caveat: Symbols that are unresolved when bringing in an object file from a library are searched for in that library first, and then the following libraries from the command line and /DEFAULTLIB (Specify Default Library)<https://docs.microsoft.com/en-us/cpp/build/reference/defaultlib-specify-default-library?view=vs-2019> directives, and then to any libraries at the beginning of the command line.”).

From: libcxx-dev <libcxx-dev-bounces at lists.llvm.org> on behalf of Louis Dionne via libcxx-dev <libcxx-dev at lists.llvm.org>
Reply-To: Louis Dionne <ldionne at apple.com>
Date: Tuesday, April 2, 2019 at 2:37 PM
To: cfe-dev <cfe-dev at lists.llvm.org>
Cc: TheAspiringHacker <TheAspiringHacker at protonmail.com>, "libcxx-dev at lists.llvm.org" <libcxx-dev at lists.llvm.org>
Subject: Re: [libcxx-dev] Is the C++ filesystem object file installed via LLVM's APT repository missing symbols?




On Apr 2, 2019, at 17:21, Louis Dionne via libcxx-dev <libcxx-dev at lists.llvm.org<mailto:libcxx-dev at lists.llvm.org>> wrote:




On Apr 1, 2019, at 19:01, Eric Fiselier via libcxx-dev <libcxx-dev at lists.llvm.org<mailto:libcxx-dev at lists.llvm.org>> wrote:


On Mon, Apr 1, 2019 at 9:46 AM TheAspiringHacker via libcxx-dev <libcxx-dev at lists.llvm.org<mailto:libcxx-dev at lists.llvm.org>> wrote:
Hello,

I have downloaded LLVM and Clang 8 from the APT repository (deb http://apt.llvm.org/xenial/<https://urldefense.proofpoint.com/v2/url?u=http-3A__apt.llvm.org_xenial_&d=DwMFAg&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6c1v3c4C7T7kyJ5MxPQqPPRPSvxC9FTOOJvF9OKPhgI&s=Fvn2T3HkYgEDOQLMyFlM5ngp1xc1hI_AfCb7Jd6ggpo&e=> llvm-toolchain-xenial-8 main). When I compile and link

#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    fs::path wd = fs::current_path();
    return 0;
}

with clang-8 -std=c++17 -stdlib=libc++ -lc++ -lc++abi -lc++fs test.cpp -v

I get the output:

clang version 8.0.0-svn356034-1~exp1~20190313094121.53 (branches/release_80)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.5.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.4.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
"/usr/lib/llvm-8/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name test.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -v -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -internal-isystem /usr/lib/llvm-8/bin/../include/c++/v1 -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/<username> -ferror-limit 19 -fmessage-length 0 -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -o /tmp/test-b088e9.o -x c++ test.cpp -faddrsig
clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
ignoring duplicate directory "/usr/include/clang/8.0.0/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/llvm-8/bin/../include/c++/v1
/usr/include/clang/8.0.0/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
"/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.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.5.0/../../.. -L/usr/lib/llvm-8/bin/../lib -L/lib -L/usr/lib -lc++ -lc++abi -lc++fs /tmp/test-b088e9.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../x86_64-linux-gnu/crtn.o
/tmp/test-b088e9.o: In function `std::__1::__fs::filesystem::current_path()':
test.cpp:(.text._ZNSt3__14__fs10filesystem12current_pathEv[_ZNSt3__14__fs10filesystem12current_pathEv]+0x14): undefined reference to `std::__1::__fs::filesystem::__current_path(std::__1::error_code*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)


I ran:

nm -C /usr/lib/llvm-8/lib/libc++fs.a | fgrep 'std::__1::__fs::filesystem::__current_path'

and got:

0000000000002540 T std::__1::__fs::filesystem::__current_path(std::__1::error_code*)
0000000000002880 T std::__1::__fs::filesystem::__current_path(std::__1::__fs::filesystem::path const&, std::__1::error_code*)

It seems that the `current_path` functions, as defined in the libc++fs.a file that I installed, do not match the overloads as documented at https://en.cppreference.com/w/cpp/filesystem/current_path<https://urldefense.proofpoint.com/v2/url?u=https-3A__en.cppreference.com_w_cpp_filesystem_current-5Fpath&d=DwMFAg&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6c1v3c4C7T7kyJ5MxPQqPPRPSvxC9FTOOJvF9OKPhgI&s=E0gAesL6qFbjGV1xY1Z5CJpYnf455FJ2JbQ1_NLfQQI&e=> or specified in the filesystem header file of libc++. According to http://libcxx.llvm.org/ts1z_status.html<https://urldefense.proofpoint.com/v2/url?u=http-3A__libcxx.llvm.org_ts1z-5Fstatus.html&d=DwMFAg&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6c1v3c4C7T7kyJ5MxPQqPPRPSvxC9FTOOJvF9OKPhgI&s=l8wb7lcPuHZoJXnCYsaVRM_qmC7avUrrsjaRI18MPGc&e=>, as of June 17, 2016, the filesystem library is complete. For comparison, the APT repository was last updated on March 27, 2019.

I do not know if perhaps I made a mistake in linking the code or installing the library. https://libcxx.llvm.org/<https://urldefense.proofpoint.com/v2/url?u=https-3A__libcxx.llvm.org_&d=DwMFAg&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6c1v3c4C7T7kyJ5MxPQqPPRPSvxC9FTOOJvF9OKPhgI&s=C0te1DBSsmWIERl3PcPtdRW03Y0iwrp1-Z2qr2thXks&e=> directed me to ask here if I'm not sure whether I found a bug.

Is this an issue with the files I downloaded from the APT repository, or is it my own mistake?

Your invocation of Clang puts -lc++fs before the source file that depends on it.
You need to put the source file before the libraries. Ex:

 clang-8 -std=c++17 -stdlib=libc++ test.cpp -lc++fs -v

Isn't that something that Clang should handle?

To clarify, what I meant is that from a very naive point of view, the order in which you provide `-l`'s on the command line shouldn't matter -- it should work as long as you provide the right set of `-l`'s. I'm puzzled every time a tool (e.g. `ld`) behaves differently based on the order of command line arguments.

Maybe there's a good reason for this, though. Maybe the cfe-dev folks can explain?

Louis

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/libcxx-dev/attachments/20190402/91049077/attachment-0001.html>


More information about the libcxx-dev mailing list