Libcopp
cross-platform coroutine library in c++
Install / Use
/learn @owent/LibcoppREADME
libcopp
Cross-platform coroutine library in C++.
CI Job Matrix
| 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 | Clang-latest | With libc++ | | MinGW64 | GCC | Dynamic linking | | Windows | Visual Studio 2022 | Static linking | | Windows | Visual Studio 2022 | Dynamic linking | | macOS | AppleClang | With libc++ |
License
License under the MIT LICENSE.
Document
Documents can be found at https://libcopp.atframe.work, API references can be found at https://libcopp.atframe.work/doxygen/html/. (Generated by MkDocs with docs/mkdocs.yml and Doxygen with docs/libcopp.doxyfile.in.)
UPGRADE FROM 1.3.X-1.4.X to 2.X
- Add
using value_type = int;intoTwhen usingcotask::task<T>. - Rename
stack_allocator_ttostack_allocator_typeinTwhen usingcotask::task<T>. - Rename
coroutine_ttocoroutine_typeinTwhen usingcotask::task<T>. - Rename
libcopp::util::*tocopp::util::. - We are not allowed to use
libcopp::util::intrusive_ptr<cotask::impl::task_impl>now, please usecotask::task<T>::ptr_typeinstead.
UPGRADE FROM 1.2.X to 1.3.X-1.4.X
- Rename
cotask::task::awaitintocotask::task::await_task. - Replace
cotask::task<TCO_MACRO, TTASK_MACRO>withcotask::task<TCO_MACRO>, we don't allow to custom id allocator now. - Replace
cotask::core::standard_int_id_allocator<uint64_t>withcopp::util::uint64_id_allocator, we don't allow to custom id allocator now. - Require gcc 4.8+, MSVC 15+(Visual Studio 2017>).
- Require cmake 3.12.0 or upper.
INSTALL
libcopp use cmake to generate makefile and switch build tools.
Prerequisites
- [required] GCC or Clang or MSVC or clang-cl support ISO C++ 11 and upper
- [required] cmake 3.16.0 and upper
- [optional] gtest 1.6.0 and upper (Better unit test supported)
- [optional] Boost.Test (Boost.Test supported)
Unix
Windows
- [required] masm (in MSVC)
- [optional] if using gtest, pthread is required.
Install with vcpkg
-
Clone and setup vcpkg (See more detail on https://github.com/Microsoft/vcpkg)
git clone https://github.com/Microsoft/vcpkg.git cd vcpkg PS> bootstrap-vcpkg.bootstrap Linux:~/$ ./bootstrap-vcpkg.sh -
Install libcopp
PS> .\vcpkg install libcopp [--triplet x64-windows-static/x64-windows/x64-windows-static-md and etc...] Linux:~/$ ./vcpkg install libcopp -
See using with cmake for cmake below.
Custom Build
-
Clone and make a build directory
git clone --single-branch --depth=1 -b master https://github.com/owent/libcopp.git mkdir libcopp/build && cd libcopp/build -
Run cmake command
# cmake <libcopp dir> [options...] cmake .. -DPROJECT_ENABLE_UNITTEST=YES -DPROJECT_ENABLE_SAMPLE=YES -
Make libcopp
cmake --build . --config RelWithDebInfo # or make [options] when using Makefile -
Run
test/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.benchmark -
Install [optional]
cmake --build . --config RelWithDebInfo --target install # or make install when using Makefile -
Then just include and link
libcopp.*/libcotask.*, or see using with cmake for cmake below.
CMake Options
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_ENABLE_MULTI_THREAD=YES|NO | [default=YES] Enable 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 |
USAGE
Using with cmake
-
Using
set(Libcopp_ROOT <where to find libcopp/INSTALL_PREFIX>) -
Just using find_package(Libcopp) to use libcopp module.
-
Example:(we assume the target name is stored in
${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.
Directly use headers and libraries
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
}
Get Start & Example
There serveral samples to use copp::coroutine_context, copp::coroutine_context_fiber and cotask::task:
- Using coroutine context
- Using coroutine task
- Using coroutine task manager
- Using stack pool
- Using
task::thenortask::await_task - Using
copp::callable_promiseof c++20 coroutine - Using
copp::generator_futurefor c++20 coroutine - Custom error (timeout for example) when using c++20 coroutine
- Let c++20 coroutine work with
cotask::task - Using Windows fiber and
SetUnhandledExceptionFilteron Windows withcotask::task - Using c++20 coroutine with channel receiver and sender
- Using stackful coroutine task with channel receiver and sender
- Using stackful coroutine with channel receiver and sender
- Using c++20 coroutine with channel receiver and sende
