how to static link with clang libc++

10,823

Solution 1

I've encountered a similar issue. After adding the -static flag, I (also) got a large number of "missing symbol" linker errors. In my case, the missing symbols all belonged to the libpthread and libc++abi libraries. Trying to add those library dependencies explicitly in the command line (-lc++abi -pthread) did not help either - this was possibly due to the order in which the default linker used by clang in my system processed the dependencies. Once I switched to the lld linker, the issue seemed to be resolved. All in all, I added the following 4 flags to the clang command: -static -lc++abi -pthread -fuse-ld=lld.

Solution 2

GNU libstdc++ and LLVM libc++ are two different implementations of the standard C++ library.

Apparently your libstdc++ doesn't yet support the Coroutines TS, so you have to stick to libc++.

To link your application statically just use -static:

clang++ testcoroutine.cpp -std=c++2a -I../asio_alone -fcoroutines-ts -stdlib=libc++ -static
Share:
10,823

Related videos on Youtube

alpha
Author by

alpha

Updated on June 04, 2022

Comments

  • alpha
    alpha almost 2 years

    I just wrote a test code for coroutine in c++2a.

    I build the code with clang 5.0 with:

    clang++ testcoroutine.cpp -std=c++2a -I../asio_alone -fcoroutines-ts -stdlib=libc++
    

    The code works fine.

    Now I want to static link the libc++.so so that I can run the a.out in other PC, I googled but only find the -static-libstdc++.

    I can not use the -static-libstdc++ because the libstdc++ does not support the coroutine.

    If I use the -static-libstdc++:

    clang++ testcoroutine.cpp -std=c++2a -I../asio_alone -fcoroutines-ts
    -static-libstdc++ 
    testcoroutine.cpp:26:10: fatal error: 'experimental/coroutine' file not found
    #include <experimental/coroutine>
    
    
     ^~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated.
    

    Any suggestion?


    The test code:

    #define ASIO_STANDALONE
    #define ASIO_HAS_STD_CHRONO
    
    #ifdef _WIN32
    #pragma warning (disable:4819)
    #pragma warning (disable:4503)
    #pragma warning (disable:4996)
    #pragma warning (disable:4100) // unref parameters
    #define _CRT_SECURE_NO_WARNINGS
    #define NOMINMAX
    #define _CRT_NONSTDC_NO_DEPRECATE
    #define WIN32_LEAN_AND_MEAN
    #endif
    
    #ifdef _WIN32
    #include <SDKDDKVer.h>
    #endif
    
    #include <stdio.h>
    #include <cstdio>
    #include <thread>
    #include <algorithm>
    #include <future>
    #include <chrono>
    #include <experimental/coroutine>
    #include <asio.hpp>
    
    // clang++ testcoroutine.cpp -std=c++2a -I../asio_alone -fcoroutines-ts -stdlib=libc++
    
    #ifndef _WIN32
    template <typename... Args>
    struct std::experimental::coroutine_traits<std::future<void>, Args...> {
        struct promise_type {
            std::promise<void> p;
            auto get_return_object() { return p.get_future(); }
            std::experimental::suspend_never initial_suspend() { return {}; }
            std::experimental::suspend_never final_suspend() { return {}; }
            void set_exception(std::exception_ptr e) { p.set_exception(std::move(e)); }
            void return_void() { p.set_value(); }
            void unhandled_exception() { std::terminate(); }
        };
    };
    #endif 
    
    template <typename R, typename P>
    auto async_await(asio::steady_timer &t, std::chrono::duration<R, P> d) {
        struct Awaiter {
            asio::steady_timer &t;
            std::chrono::duration<R, P> d;
            asio::error_code ec;
    
            bool await_ready() { return d.count() == 0; }
            void await_resume() {
                if (ec)
                    throw ec;
            }
            void await_suspend(std::experimental::coroutine_handle<> coro) {
                t.expires_from_now(d);
                t.async_wait([this, coro](auto ec) mutable {
                    this->ec = ec;
                    coro.resume();
                });
            }
        };
        return Awaiter{ t, d };
    }
    
    
    std::future<void> sleepy(asio::io_service &io) {
        asio::steady_timer timer(io);
        co_await async_await(timer, std::chrono::milliseconds(100));
        puts("tick1");
        co_await async_await(timer, std::chrono::milliseconds(100));
        puts("tick2");
        co_await async_await(timer, std::chrono::milliseconds(100));
        puts("tick3");
    }
    
    int main()
    {      
        asio::io_service io;
        sleepy(io);
        io.run();
        return 0;
    }