Using LLD to link against third-party libraries? How?

How do I use LLD to link against third-party libraries? I’ve tried providing the full path along with the library name in the same argument with the -L flag (i.e. -L path/to/library.lib) without success. I really want to know how I can do this. Thanks in advance.

You might need to add
-fuse-ld=lld to your LDFLAGS
make sure you also built and have installed the lld component of the llvm tool chain.

Best

I add the -fuse-ld=lld flag to the compiler command line itself. And I included LLD when I built LLVM (I checked out the mono repo and built that version).

What command line arguments should I pass to LLD when I want to link against third-party libraries? That’s what I’m asking.

That depends on the library that you’d like to link against, it’s usually in the documentation of that project.

What project are you trying to link and what linker flags have you tried so far?

Best

I already mentioned what flag I tried. It’s in the first email in this thread. And I want to link against Boost.System and the Jinja2Cpp library (the latter’s documentation can be found here: https://github.com/flexferrum/Jinja2Cpp . And I also have some GUI applications using FLTK as well that I want to try to build using LLVM as well, so I’ll have to know how to link against FLFK’s libraries too.

The documentation on that github page says c++14

make sure your
CXXFLAGS have -std=c++14
LDFLAGS have -fuse-ld=lld -lc++ -lc++abi -lm -lc

Going forward If the link fails u have to provide more information as to what errors ur getting.

Best

In my code here https://github.com/DragonOsman/currency_converter , I used C++17 and managed to get it to work (though I’m only using std::map::insert_or_assign() from C++17). And I’m using Windows, so I shouldn’t use LDFLAGS or CXXFLAGS as environment variables. I’ll use them directly on the compiler command line instead. The libraries I need to link against are C:/boost_1_68_0/stage/lib/libboost_system-vc141-mt-x64-1_68.lib and C:/Jinja2Cpp/install_x64/lib/static/jinja2cpp.lib.

I tried to build it with this flag:
"
clang++ -std=c++17 -Wall -pedantic -D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING -Dvariant_CONFIG_SELECT_VARIANT=variant_VARIANT_NONSTD -D_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32 -D_WIN32_WINDOWS -D_NDEBUG -fexceptions -IC:/Jinja2Cpp/install_x64/include -IC:/json/single_include -IC:/boost_1_68_0 -LC:/boost_1_68_0/stage/lib/libboost_system-vc141-mt-x64-1_68.lib -LC:/Jinja2Cpp/install_x64/lib/static/jinja2cpp.lib currency_converter.cpp -o currency_converter.exe
"
And I got these warnings and errors from LLD:

"
lld-link: warning: C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o: locally defined symbol imported: __std_terminate (defined in libvcruntime.lib(ehhelpers.obj)) [LNK4217]

lld-link: error: undefined symbol: “public: __cdecl jinja2::Template::Template(class jinja2::TemplateEnv *)” (??0Template@jinja2@@QEAA@PEAVTemplateEnv@1@@Z)​

referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“void __cdecl handle_request<struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class std::allocator, struct server_session::send_lambda &>(class boost::basic_string_view<char, struct std::char_traits>, struct boost::beast::http::message<1, struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class boost::beast::http::basic_fields<class std::allocator>> &&, struct server_session::send_lambda &, char const *, char const *)” (??$handle_request@U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$allocator@D@std@@AEAUsend_lambda@server_session@@@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@boost@@$$QEAU?$message@$00U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$basic_fields@V?$allocator@D@std@@@234@@http@beast@1@AEAUsend_lambda@server_session@@PEBD3@Z))​

lld-link: error: undefined symbol: “public: class nonstd::expected_lite::expected<void, class jinja2::ErrorInfoTpl> __cdecl jinja2::Template::LoadFromFile(class std::basic_string<char, struct std::char_traits, class std::allocator> const &)” (?LoadFromFile@Template@jinja2@@QEAA?AV?$expected@XV?$ErrorInfoTpl@D@jinja2@@@expected_lite@nonstd@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“void __cdecl handle_request<struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class std::allocator, struct server_session::send_lambda &>(class boost::basic_string_view<char, struct std::char_traits>, struct boost::beast::http::message<1, struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class boost::beast::http::basic_fields<class std::allocator>> &&, struct server_session::send_lambda &, char const *, char const *)” (??$handle_request@U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$allocator@D@std@@AEAUsend_lambda@server_session@@@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@boost@@$$QEAU?$message@$00U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$basic_fields@V?$allocator@D@std@@@234@@http@beast@1@AEAUsend_lambda@server_session@@PEBD3@Z))​

lld-link: error: undefined symbol: “public: class std::basic_string<char, struct std::char_traits, class std::allocator> __cdecl jinja2::Template::RenderAsString(class std::unordered_map<class std::basic_string<char, struct std::char_traits, class std::allocator>, class jinja2::Value, struct std::hash<class std::basic_string<char, struct std::char_traits, class std::allocator>>, struct std::equal_to<class std::basic_string<char, struct std::char_traits, class std::allocator>>, class std::allocator<struct std::pair<class std::basic_string<char, struct std::char_traits, class std::allocator> const, class jinja2::Value>>> const &)” (?RenderAsString@Template@jinja2@@QEAA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$unordered_map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VValue@jinja2@@U?$hash@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@U?$equal_to@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VValue@jinja2@@@std@@@2@@4@@Z)​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“void __cdecl handle_request<struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class std::allocator, struct server_session::send_lambda &>(class boost::basic_string_view<char, struct std::char_traits>, struct boost::beast::http::message<1, struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class boost::beast::http::basic_fields<class std::allocator>> &&, struct server_session::send_lambda &, char const *, char const *)” (??$handle_request@U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$allocator@D@std@@AEAUsend_lambda@server_session@@@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@boost@@$$QEAU?$message@$00U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$basic_fields@V?$allocator@D@std@@@234@@http@beast@1@AEAUsend_lambda@server_session@@PEBD3@Z))​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“void __cdecl handle_request<struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class std::allocator, struct server_session::send_lambda &>(class boost::basic_string_view<char, struct std::char_traits>, struct boost::beast::http::message<1, struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class boost::beast::http::basic_fields<class std::allocator>> &&, struct server_session::send_lambda &, char const *, char const *)” (??$handle_request@U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$allocator@D@std@@AEAUsend_lambda@server_session@@@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@boost@@$$QEAU?$message@$00U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$basic_fields@V?$allocator@D@std@@@234@@http@beast@1@AEAUsend_lambda@server_session@@PEBD3@Z))​

lld-link: error: undefined symbol: “public: __cdecl jinja2::Template::~Template(void)” (??1Template@jinja2@@QEAA@XZ)​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“void __cdecl handle_request<struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class std::allocator, struct server_session::send_lambda &>(class boost::basic_string_view<char, struct std::char_traits>, struct boost::beast::http::message<1, struct boost::beast::http::basic_string_body<char, struct std::char_traits, class std::allocator>, class boost::beast::http::basic_fields<class std::allocator>> &&, struct server_session::send_lambda &, char const *, char const *)” (??$handle_request@U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$allocator@D@std@@AEAUsend_lambda@server_session@@@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@boost@@$$QEAU?$message@$00U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$basic_fields@V?$allocator@D@std@@@234@@http@beast@1@AEAUsend_lambda@server_session@@PEBD3@Z))​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“int void __cdecl handle_request<struct boost::beast::http::basic_string_body<char, struct std::char_traits<char>, class std::allocator<char>>, class std::allocator<char>, struct server_session::send_lambda &>(class boost::basic_string_view<char, struct std::char_traits<char>>, struct basic_string_view<char, struct std::char_traits<char>>::beast::http::message<1, struct boost::beast::http::basic_string_body<char, struct std::char_traits<char>, class std::allocator<char>>, class boost::beast::http::basic_fields<class std::allocator<char>>> &&, struct server_session::send_lambda &, char const *, char const *)'::1’::dtor$114” (?dtor$114@?0???$handle_request@U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$allocator@D@std@@AEAUsend_lambda@server_session@@@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@boost@@$$QEAU?$message@$00U?$basic_string_body@DU?$char_traits@D@std@@V?$allocator@D@2@@http@beast@boost@@V?$basic_fields@V?$allocator@D@std@@@234@@http@beast@1@AEAUsend_lambda@server_session@@PEBD3@Z@4HA))​

lld-link: warning: C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o: locally defined symbol imported: _CxxThrowException (defined in libvcruntime.lib(throw.obj)) [LNK4217]​
lld-link: error: undefined symbol: “class boost::system::error_category const & __cdecl boost::system::detail::system_category_ncx(void)” (?system_category_ncx@detail@system@boost@@YAAEBVerror_category@23@XZ)​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“class boost::system::error_category const & __cdecl boost::system::system_category(void)” (?system_category@system@boost@@YAAEBVerror_category@12@XZ))​

lld-link: warning: C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o: locally defined symbol imported: __RTDynamicCast (defined in libvcruntime.lib(rtti.obj)) [LNK4217]​
lld-link: error: undefined symbol: “class boost::system::error_category const & __cdecl boost::system::detail::generic_category_ncx(void)” (?generic_category_ncx@detail@system@boost@@YAAEBVerror_category@23@XZ)​
referenced by C:\Users\Osman\AppData\Local\Temp\currency_converter-264ae1.o:(“class boost::system::error_category const & __cdecl boost::system::generic_category(void)” (?generic_category@system@boost@@YAAEBVerror_category@12@XZ))​
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
"

What do you mean by "third-party" here?

To link with a library, either:

1. Add the library to the link line. Not with any command line switches in front, just add it as you would an object file. You mention ".lib" so I'm assuming you're on Windows or something similar? In that case, you'd just have "foo.obj bar.obj path/to/library.lib". Just list it like you would any object file.

2. Add the path containing the library to the library search directory (that's what uppercase "-L" does) then specify the name of the library via "-l". In your case that would look something like "-Lpath/to foo.obj bar.obj -llibrary". For Unix-like linkers, this will search for the files "liblibrary.so" and "liblibrary.a" in the search paths specified via -L ("lib" prepended to the name of the library, and ".so" or ".a" extensions appended). I'm not sure what rules GNU LD, Gold or LLD use to figure out what files to search on Windows host platforms.

-Fabian

@blubee blubeeme So what do you think? Got any ideas?

Are you linking with a C++ compiler? A lot of those missing symbols
look like they come from the C++ standard library.

                          -David

Osman Zakir via llvm-dev <llvm-dev@lists.llvm.org> writes:

LLVM on a Developer Command Prompt. The ones I want to fix first are the ones from Boost and Jinja2Cpp. I saw some from those as well.

If there any standard library ones missing, could it be because I couldn’t get it to build libcxx? I did try to include that, but it seems to be missing. What should I do?

I couldn’t get it to build libcxx…
You need c++ and c++abi to compile c++ code.

I see you’re using lld-link, so we’re talking about Windows here.

Have you gotten it working with the Microsoft linker? Because if so, just replace link.exe with lld-link.exe and it will work.

Btw, it’s a bit odd to use clang++ on Windows. The recommended workflow is to use clang-cl. It’s possible to use clang++, but you’re just setting yourself up for more difficulty

So how do I get it to build libcxx and libcxxabi? I got it from the mono repo and enabled lld, clang, libcxx and libcxxabi. But I built the two main CMake targets only–all_build and install. What else do I have to do? Please let me know.

Do you need to build libcxx and libcxxabi or is it sufficient to link against a host toolchain’s c++ lib? Bootstrapping the c++ lib adds unnecessary complexity here if I follow the goal. Why build lld, for that matter? Do you have local changes to lld? If you aren’t working on adding features to lld/clang/libcxx, consider getting the host tools you need from https://releases.llvm.org/

So if you are seeing unresolved symbols, are you sure you are linking against all of the necessary dependecies? I think Zachary’s suggestions are a good starting point. He suggested clang-cl. Did that change your results? Can you do the same build using visual studio’s tools? If so, it sounds straightforward to change to clang-cl.

I would agree with the next email from### Brian Cain

If you do not have specific reason to want to use llvm lld try to use your system provided c++ linker.

Bootstrapping the llvm c++ c++abi can be troublesome on Unix like platforms and I have no experience doing anything like that on windows.

If you already have a c++ toochain and still want to attempt this then you’ll need to svn checkout or git clone a version of the llvm toolchain and build it with your native toolchain then switch to using clang and lld.

if you do not have a native c++ toolchain; let’s cross that bridge only if you need to.

A complete LLVM toolchain includes
llvm
clang
clang-extra-tools
lld
lldb
polly
compiler-rt
openmp
libcxx
libcxx-abi
testsuite
There’s “Getting Started Quickly (A Summary” : https://llvm.org/docs/GettingStarted.html

With steps to build a complete toolchain. Compilation could take a long time.

It would be simpler to use your native c++ and linker unless they do not provide c++17 in which case the above link can get you started.

Best

How can I tell CMake during the configuration step where to find my zlib installation?

You shouldn’t need zlib to build. I think we discussed in a previous thread that the only components you should need to complete a build are Microsoft Visual Studio, git, and CMake.

If you want to bootstrap clang and lld using itself, then you should pass -DCMAKE_C_COMPILER=path/to/clang-cl.exe -DCMAKE_CXX_COMPILER=path/to/clang-cl.exe -DCMAKE_LINKER=path/to/lld-link.exe.

Note the clang-cl.exe. Not clang.exe or clang++.exe.

Do you have a specific reason for enabling libcxx and libcxxabi? Because I would strongly suggest disabling them otherwise