Cross-platform coroutine library in C++ .
| Target System | Toolchain | Note |
|---|---|---|
| Linux | GCC | Static linking |
| Linux | GCC | Dynamic linking |
| Linux | GCC-latest | |
| Linux | GCC-latest | No Exception |
| Linux | GCC-latest | Thread Unsafe |
| Linux | GCC 4.8 | Legacy |
| Linux | Clang-latest | With libc++ |
| MinGW64 | GCC | Dynamic linking |
| Windows | Visual Studio 2019 | Static linking |
| Windows | Visual Studio 2019 | Dynamic linking |
| Windows | Visual Studio 2017 | Legacy,Static linking |
| macOS | AppleClang | With libc++ |
License under the MIT LICENSE
Documents can be found at https://libcopp.atframe.work , API references canbe found at https://libcopp.atframe.work/doxygen/html/ .(Generated by sphinx and doxygen with docs/sphinx and docs/libcopp.doxyfile.in).
using value_type = int; into T when using cotask::task<T>.stack_allocator_t to stack_allocator_type in T when using cotask::task<T>.coroutine_t to coroutine_type in T when using cotask::task<T>.libcopp::util::* to copp::util::.libcopp::util::intrusive_ptr<cotask::impl::task_impl> now, please use cotask::task<T>::ptr_type instead.cotask::task::await into cotask::task::await_task
cotask::task<TCO_MACRO, TTASK_MACRO> with cotask::task<TCO_MACRO> , we don't allow to custom id allocator now.cotask::core::standard_int_id_allocator<uint64_t> with copp::util::uint64_id_allocator , we don't allow to custom id allocator now.ar, as, ld (binutils) or llvmgit clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
PS> bootstrap-vcpkg.bootstrap
Linux:~/$ ./bootstrap-vcpkg.shPS> .vcpkg install libcopp [--triplet x64-windows-static/x64-windows/x64-windows-static-md and etc...]
Linux:~/$ ./vcpkg install libcoppSee :ref:`using with cmake <usage-using with-cmake>` for cmake below.
git clone --single-branch --depth=1 -b master https://github.com/owent/libcopp.git
mkdir libcopp/build && cd libcopp/build# cmake <libcopp dir> [options...]
cmake .. -DPROJECT_ENABLE_UNITTEST=YES -DPROJECT_ENABLE_SAMPLE=YEScmake --build . --config RelWithDebInfo # or make [options] when using Makefiletest/sample/benchmark [optional]
# Run test => Required: PROJECT_ENABLE_UNITTEST=YES
ctest -VV . -C RelWithDebInfo -L libcopp.unit_test
# Run sample => Required: PROJECT_ENABLE_SAMPLE=YES
ctest -VV . -C RelWithDebInfo -L libcopp.sample
# Run benchmark => Required: PROJECT_ENABLE_SAMPLE=YES
ctest -VV . -C RelWithDebInfo -L libcopp.benchmarkcmake --build . --config RelWithDebInfo --target install # or make install when using MakefileThen just include and link libcopp.*/libcotask.*, or see :ref:`using with cmake <usage-using with-cmake>` for cmake below.
Options can be cmake options. such as set compile toolchains, source directory or options of libcopp that control build actions. libcopp options are listed below:
| Option | Description |
|---|---|
| BUILD_SHARED_LIBS=YES|NO | [default=NO] Build dynamic library. |
| LIBCOPP_ENABLE_SEGMENTED_STACKS=YES|NO | [default=NO] Enable split stack supported context.(it's only availabe in linux and gcc 4.7.0 or upper) |
| LIBCOPP_ENABLE_VALGRIND=YES|NO | [default=YES] Enable valgrind supported context. |
| PROJECT_ENABLE_UNITTEST=YES|NO | [default=NO] Build unit test. |
| PROJECT_ENABLE_SAMPLE=YES|NO | [default=NO] Build samples. |
| LIBCOPP_LOCK_DISABLE_THIS_MT=YES|NO | [default=NO] Disable multi-thread support for copp::this_coroutine and cotask::this_task. |
| LIBCOPP_DISABLE_ATOMIC_LOCK=YES|NO | [default=NO] Disable multi-thread support. |
| LIBCOTASK_ENABLE=YES|NO | [default=YES] Enable build libcotask. |
| LIBCOPP_FCONTEXT_USE_TSX=YES|NO | [default=YES] Enable Intel Transactional Synchronisation Extensions (TSX). |
| LIBCOPP_MACRO_TLS_STACK_PROTECTOR=YES|NO | [default=NO] Users need set LIBCOPP_MACRO_TLS_STACK_PROTECTOR=ON when compiling with -fstack-protector.
Because it changes the default context switching logic. |
| GTEST_ROOT=[path] | set gtest library install prefix path |
| BOOST_ROOT=[path] | set Boost.Test library install prefix path |
set(Libcopp_ROOT <where to find libcopp/INSTALL_PREFIX>)
${CUSTOM_TARGET_NAME})find_package(Libcopp CONFIG REQUIRED)
target_link_libraries(${CUSTOM_TARGET_NAME} libcopp::cotask)
# Or just using copp by target_link_libraries(${CUSTOM_TARGET_NAME} libcopp::copp)If using MSVC and vcpkg, CRT must match the triplet of vcpkg, these codes below may be helpful:
if (MSVC AND VCPKG_TOOLCHAIN)
if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
endif()
if (VCPKG_TARGET_TRIPLET MATCHES "^.*windows-static$")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "")
else ()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" CACHE STRING "")
endif ()
endif ()See more detail on https://github.com/Microsoft/vcpkg/tree/master/ports/libcopp .
Just include headers and linking library file of your platform to use libcopp.
LIBCOPP_PREFIX=<WHERE TO INSTALL libcopp>
# Example command for build sample with gcc 4.9 or upper on Linux
for source in sample_readme_*.cpp; do
g++ -std=c++14 -O2 -g -ggdb -Wall -Werror -fPIC -rdynamic -fdiagnostics-color=auto -Wno-unused-local-typedefs
-I$LIBCOPP_PREFIX/include -L$LIBCOPP_PREFIX/lib64 -lcopp -lcotask $source -o $source.exe;
done
# Example command for build sample with clang 3.9 or upper and libc++ on Linux
for source in sample_readme_*.cpp; do
clang++ -std=c++17 -stdlib=libc++ -O2 -g -ggdb -Wall -Werror -fPIC -rdynamic
-I$LIBCOPP_PREFIX/include -L$LIBCOPP_PREFIX/lib64 -lcopp -lcotask -lc++ -lc++abi
$source -o $source.exe;
done
# AppleClang on macOS just like those scripts upper.
# If you are using MinGW on Windows, it's better to add -static-libstdc++ -static-libgcc to
# use static linking and other scripts are just like those on Linux.# Example command for build sample with MSVC 1914 or upper on Windows & powershell(Debug Mode /MDd)
foreach ($source in Get-ChildItem -File -Name .sample_readme_*.cpp) {
cl /nologo /MP /W4 /wd"4100" /wd"4125" /EHsc /std:c++17 /Zc:__cplusplus /O2 /MDd /I$LIBCOPP_PREFIX/include $LIBCOPP_PREFIX/lib64/copp.lib $LIBCOPP_PREFIX/lib64/cotask.lib $source
}There serveral samples to use copp::coroutine_context 、 copp::coroutine_context_fiber and cotask::task :
task::then or task::await_task
copp::callable_promise of c++20 coroutinecopp::generator_future for c++20 coroutinecotask::task
SetUnhandledExceptionFilter on Windows with cotask::task
All sample codes can be found on :ref:`EXAMPLES <examples_doc_anchor>` and sample .
Split stack support: if in Linux and user gcc 4.7.0 or upper, add -DLIBCOPP_ENABLE_SEGMENTED_STACKS=YES to use split stack supported context.
It's recommanded to use stack pool instead of gcc splited stack.
Please see CI output for latest benchmark report. Click to visit Github Actions .
Q: How to enable c++20 coroutine
/std:c++latest /await for MSVC 1932 and below or -std=c++20 -fcoroutines-ts -stdlib=libc++ for clang 13 and below or -std=c++20 -fcoroutines for gcc 10.If you can just use -std=c++20 -stdlib=libc++ clang 14 or above, -astd=c++20 for gcc 11 or above, and /std:c++latest for MSVC 1932 or above.
Q: Will libcopp handle exception?
Q: Why SetUnhandledExceptionFilter can not catch the unhandled exception in a coroutine?
SetUnhandledExceptionFilter only works with Windows Fiber, please see sample/sample_readme_11.cpp for details.If you has any question, please create a issue and provide the information of your environments. For example:
cmake .. -G "Visual Studio 16 2019" -A x64 -DLIBCOPP_FCONTEXT_USE_TSX=ON -DPROJECT_ENABLE_UNITTEST=ON -DPROJECT_ENABLE_SAMPLE=ON-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=%cd%/install-prefix / cmake .. -G Ninja -DLIBCOPP_FCONTEXT_USE_TSX=ON -DPROJECT_ENABLE_UNITTEST=ON -DPROJECT_ENABLE_SAMPLE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/opt/libcopp
cmake --build . -j
CC 、 CXX 、 AR and etc.