Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to static link with clang libc++

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;
}
like image 694
alpha Avatar asked Oct 16 '17 07:10

alpha


People also ask

Can you statically link libc?

Statically linking libc is it's own minefield. It can and is done but even if you statically link everything else you should almost always dynamically link against your platform's libc. Statically linking libc is harder than dynamically linking it, but certainly easier than rewriting it.

Is libc automatically linked?

libc is always searched automatically.

Is libc a dynamic library?

However libc has not been linked in statically, only dynamically, so it is another failed attempt.

How do I know if libc ++ is installed?

Type ldconfig -p | grep libc++ into the terminal. It does not matter what system you are using. If libc++ is not installed, the terminal will not say anything. If it is installed, it will display the available versions.


2 Answers

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
like image 131
rustyx Avatar answered Oct 19 '22 03:10

rustyx


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.

like image 32
SomeStrangeUser Avatar answered Oct 19 '22 05:10

SomeStrangeUser