diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2f520935..bede8f33 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -9,7 +9,8 @@ on: paths: - "include/**" - "src/**" - - "test/**" + - "tests/**" + - "examples/**" - "cmake/**" - "Makefile" - "CMakePresets.json" @@ -20,7 +21,8 @@ on: paths: - "include/**" - "src/**" - - "test/**" + - "tests/**" + - "examples/**" - "cmake/**" - "Makefile" - "CMakePresets.json" @@ -52,4 +54,5 @@ jobs: run: CXX=${{ matrix.compiler }} cmake --workflow --preset ${{ matrix.preset }} - name: Linux ${{ matrix.compiler }} sanitizer + if: startsWith(matrix.preset, 'debug') run: CXX=${{ matrix.compiler }} make all diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 6df6ae70..d4de55eb 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -9,7 +9,8 @@ on: paths: - "include/**" - "src/**" - - "test/**" + - "tests/**" + - "examples/**" - "cmake/**" - "Makefile" - "CMakePresets.json" @@ -20,7 +21,8 @@ on: paths: - "include/**" - "src/**" - - "test/**" + - "tests/**" + - "examples/**" - "cmake/**" - "Makefile" - "CMakePresets.json" @@ -60,7 +62,7 @@ jobs: run: CXX=$(brew --prefix llvm@18)/bin/clang++ cmake --workflow --preset ${{ matrix.preset }} - name: macos clang++-18 sanitizer - if: startsWith(matrix.compiler, 'clang') + if: startsWith(matrix.compiler, 'clang') && startsWith(matrix.preset, 'debug') run: CXX=$(brew --prefix llvm@18)/bin/clang++ make all - name: macos g++ ${{ matrix.preset }} @@ -69,5 +71,5 @@ jobs: # TODO: fails with AppleClang 16.0.0 on CI! # - name: macos g++ sanitizer - # if: startsWith(matrix.compiler, 'g++') + # if: startsWith(matrix.compiler, 'g++') && startsWith(matrix.preset, 'debug') # run: CXX=${{ matrix.compiler }} make all diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8205efdb..3474fcd2 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -9,7 +9,8 @@ on: paths: - "include/**" - "src/**" - - "test/**" + - "tests/**" + - "examples/**" - "cmake/**" - "CMakePresets.json" - "CMakeLists.txt" @@ -19,7 +20,8 @@ on: paths: - "include/**" - "src/**" - - "test/**" + - "tests/**" + - "examples/**" - "cmake/**" - "CMakePresets.json" - "CMakeLists.txt" @@ -32,8 +34,7 @@ jobs: fail-fast: false matrix: - # TODO: sanitizer: [debug, release] - sanitizer: [release] + preset: [debug, release] # TODO: compiler: [cl, clang-cl] compiler: [cl] @@ -48,18 +49,18 @@ jobs: # - name: build environment # run: pip install -r requirements.txt - - name: cmake workflow ${{ matrix.sanitizer }} + - name: cmake workflow ${{ matrix.preset }} shell: bash run: | cmake --version ninja --version - CXX=${{ matrix.compiler }} cmake --workflow --preset ${{ matrix.sanitizer }} + CXX=${{ matrix.compiler }} cmake --workflow --preset ${{ matrix.preset }} # - name: configure - # run: CXX=${{ matrix.compiler }} cmake --preset ${{ matrix.sanitizer }} + # run: CXX=${{ matrix.compiler }} cmake --preset ${{ matrix.preset }} # - name: build - # run: cmake --build --preset ${{ matrix.sanitizer }} + # run: cmake --build --preset ${{ matrix.preset }} # - name: ctest - # run: ctest --preset ${{ matrix.sanitizer }} + # run: ctest --preset ${{ matrix.preset }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 235b3dc3..c6874da7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,10 @@ cmake_minimum_required(VERSION 3.25...3.31) project(beman_execution26 VERSION 0.0.1 LANGUAGES CXX) +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + message(FATAL_ERROR "In-source builds are not allowed!") +endif() + set(TARGET_NAME execution26) set(TARGET_NAMESPACE beman) # FIXME: not used in install(EXPORT ...) CK? set(TARGET_PREFIX ${TARGET_NAMESPACE}.${TARGET_NAME}) @@ -15,13 +19,58 @@ set(TARGET_ALIAS ${TARGET_LIBRARY}::${TARGET_LIBRARY}) set(TARGET_PACKAGE_NAME ${PROJECT_NAME}-config) set(TARGETS_EXPORT_NAME ${PROJECT_NAME}-targets) -if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) - message(FATAL_ERROR "In-source builds are not allowed!") -endif() - include(GNUInstallDirs) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) +if(CMAKE_BUILD_TYPE STREQUAL Debug) + include(FetchContent) + + # Add project_options from https://github.com/aminya/project_options + # Change the version in the following URL to update the package + # (watch the releases of the repository for future updates) + set(PROJECT_OPTIONS_VERSION "v0.41.0") + FetchContent_Declare( + _project_options URL https://github.com/aminya/project_options/archive/refs/tags/${PROJECT_OPTIONS_VERSION}.zip + ) + FetchContent_MakeAvailable(_project_options) + include(${_project_options_SOURCE_DIR}/Index.cmake) + + # Initialize project_options variable related to this project + # This overwrites `project_options` and sets `project_warnings` + # uncomment to enable the options. Some of them accept one or more inputs: + project_options( + PREFIX + ${PROJECT_NAME} + ENABLE_CACHE + # NO! # ENABLE_CLANG_TIDY + # NO! ENABLE_VS_ANALYSIS + # ENABLE_INTERPROCEDURAL_OPTIMIZATION + # ENABLE_NATIVE_OPTIMIZATION + # ENABLE_DOXYGEN + # ENABLE_COVERAGE + ENABLE_SANITIZER_ADDRESS + ENABLE_SANITIZER_UNDEFINED + # TODO: ENABLE_SANITIZER_THREAD + # FIXME: on Linux only with clang++? ENABLE_SANITIZER_MEMORY + ENABLE_SANITIZER_POINTER_COMPARE + ENABLE_SANITIZER_POINTER_SUBTRACT + ENABLE_CONTROL_FLOW_PROTECTION + ENABLE_STACK_PROTECTION + ENABLE_OVERFLOW_PROTECTION + # ENABLE_ELF_PROTECTION + # ENABLE_RUNTIME_SYMBOLS_RESOLUTION + # ENABLE_COMPILE_COMMANDS_SYMLINK + # ENABLE_PCH + # PCH_HEADERS + # WARNINGS_AS_ERRORS + # ENABLE_INCLUDE_WHAT_YOU_USE + # ENABLE_GCC_ANALYZER + # ENABLE_BUILD_WITH_TIME_TRACE + # TODO: buggy! ENABLE_UNITY + # LINKER "lld" + ) +endif() + add_subdirectory(src/beman/execution26) if(PROJECT_IS_TOP_LEVEL) @@ -50,4 +99,5 @@ install( DESTINATION ${INSTALL_CONFIGDIR} ) +set(CPACK_GENERATOR TGZ) include(CPack) diff --git a/Makefile b/Makefile index fab7c375..02a714fa 100644 --- a/Makefile +++ b/Makefile @@ -4,16 +4,17 @@ MAKEFLAGS+= --no-builtin-rules # Disable the built-in implicit rules. MAKEFLAGS+= --warn-undefined-variables # Warn when an undefined variable is referenced. -SANITIZERS = release debug usan # TODO: lsan -OS := $(shell /usr/bin/uname) -ifeq ($(OS),Darwin) - SANITIZERS += tsan -endif -ifeq ($(OS),Linux) - SANITIZERS += asan # TODO: msan -endif - -.PHONY: default doc run update check ce todo distclean clean codespell clang-tidy build test all format $(SANITIZERS) +SANITIZERS := run +# SANITIZERS = usan # TODO: lsan +# OS := $(shell /usr/bin/uname) +# ifeq ($(OS),Darwin) +# SANITIZERS += tsan # TODO: asan +# endif +# ifeq ($(OS),Linux) +# SANITIZERS += asan # TODO: tsan msan +# endif + +.PHONY: default release debug doc run update check ce todo distclean clean codespell clang-tidy build test install all format $(SANITIZERS) SYSROOT ?= TOOLCHAIN ?= @@ -27,8 +28,10 @@ ifeq ($(CXX_BASE),clang++) COMPILER=clang++ endif -CXX_FLAGS = -g -SANITIZER = release +LDFLAGS ?= +SAN_FLAGS ?= +CXX_FLAGS ?= -g +SANITIZER ?= default SOURCEDIR = $(CURDIR) BUILDROOT = build BUILD = $(BUILDROOT)/$(SANITIZER) @@ -36,25 +39,29 @@ EXAMPLE = beman.execution26.examples.stop_token CMAKE_CXX_COMPILER=$(COMPILER) ifeq ($(SANITIZER),release) - CXX_FLAGS = -O3 -Wpedantic -Wall -Wextra -Wshadow # TODO: -Werror + CXX_FLAGS = -O3 -Wpedantic -Wall -Wextra -Wno-shadow -Werror endif ifeq ($(SANITIZER),debug) CXX_FLAGS = -g endif ifeq ($(SANITIZER),msan) SAN_FLAGS = -fsanitize=memory + LDFLAGS = $(SAN_FLAGS) endif ifeq ($(SANITIZER),asan) SAN_FLAGS = -fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize-address-use-after-scope endif ifeq ($(SANITIZER),usan) SAN_FLAGS = -fsanitize=undefined + LDFLAGS = $(SAN_FLAGS) endif ifeq ($(SANITIZER),tsan) SAN_FLAGS = -fsanitize=thread + LDFLAGS = $(SAN_FLAGS) endif ifeq ($(SANITIZER),lsan) SAN_FLAGS = -fsanitize=leak + LDFLAGS = $(SAN_FLAGS) endif default: test @@ -67,20 +74,27 @@ run: test doc: doxygen docs/Doxyfile -release: test - -$(SANITIZERS): - $(MAKE) SANITIZER=$@ +# $(SANITIZERS): +# $(MAKE) SANITIZER=$@ build: - @mkdir -p $(BUILD) - cd $(BUILD); CC=$(CXX) cmake -G Ninja $(SOURCEDIR) $(TOOLCHAIN) $(SYSROOT) -DCMAKE_CXX_COMPILER=$(CXX) -DCMAKE_CXX_FLAGS="$(CXX_FLAGS) $(SAN_FLAGS)" + CC=$(CXX) cmake --fresh -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \ + -DCMAKE_CXX_COMPILER=$(CXX) # XXX -DCMAKE_CXX_FLAGS="$(CXX_FLAGS) $(SAN_FLAGS)" cmake --build $(BUILD) +# NOTE: without install! CK test: build - # cmake --workflow --preset $(SANITIZER) ctest --test-dir $(BUILD) --rerun-failed --output-on-failure +install: test + cmake --install $(BUILD) --prefix /opt/local + +release: + cmake --workflow --preset $@ --fresh + +debug: + cmake --workflow --preset $@ --fresh + ce: @mkdir -p $(BUILD) bin/mk-compiler-explorer.py $(BUILD) diff --git a/cmake/CMakeDarwinPresets.json b/cmake/CMakeDarwinPresets.json index c7ded969..78efdf49 100644 --- a/cmake/CMakeDarwinPresets.json +++ b/cmake/CMakeDarwinPresets.json @@ -8,8 +8,7 @@ "name": "debug-base-Darwin", "hidden": true, "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_CXX_FLAGS": "-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" + "CMAKE_BUILD_TYPE": "Debug" }, "condition": { "type": "equals", @@ -21,8 +20,7 @@ "name": "release-base-Darwin", "hidden": true, "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo", - "CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wno-shadow -Wconversion -Wsign-conversion -Wcast-align -Wcast-qual -Woverloaded-virtual -Wformat=2 -Wno-error" + "CMAKE_BUILD_TYPE": "RelWithDebInfo" }, "condition": { "type": "equals", diff --git a/cmake/CMakeLinuxPresets.json b/cmake/CMakeLinuxPresets.json index 3e186643..beb1c487 100644 --- a/cmake/CMakeLinuxPresets.json +++ b/cmake/CMakeLinuxPresets.json @@ -8,8 +8,7 @@ "name": "debug-base-Linux", "hidden": true, "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_CXX_FLAGS": "-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=leak -fsanitize=undefined" + "CMAKE_BUILD_TYPE": "Debug" }, "condition": { "type": "equals", diff --git a/cmake/CMakeWindowsPresets.json b/cmake/CMakeWindowsPresets.json index f565f614..d8834f2c 100644 --- a/cmake/CMakeWindowsPresets.json +++ b/cmake/CMakeWindowsPresets.json @@ -13,8 +13,7 @@ "root-config" ], "cacheVariables": { - "CMAKE_CXX_COMPILER": "cl", - "CMAKE_CXX_FLAGS": "/W3 /EHsc /w14242 /w14254 /w14263 /w14265 /w14287 /w14289 /w14296 /w14311 /w14545 /w14546 /w14547 /w14549 /w14555 /w14640 /w14826 /w14928 /WX" + "CMAKE_CXX_COMPILER": "cl" }, "condition": { "type": "equals", diff --git a/include/beman/execution26/detail/schedule_from.hpp b/include/beman/execution26/detail/schedule_from.hpp index 50aa66ea..ccb8bf07 100644 --- a/include/beman/execution26/detail/schedule_from.hpp +++ b/include/beman/execution26/detail/schedule_from.hpp @@ -120,7 +120,7 @@ struct impls_for<::beman::execution26::detail::schedule_from_t> : ::beman::execu static constexpr bool nothrow() { return noexcept(::beman::execution26::connect(::beman::execution26::schedule(::std::declval()), receiver_t{nullptr})); - }; + } explicit state_type(Scheduler& sch, Receiver& receiver) noexcept(nothrow()) : state_base{receiver}, op_state(::beman::execution26::connect(::beman::execution26::schedule(sch), receiver_t{this})) {} diff --git a/src/beman/execution26/CMakeLists.txt b/src/beman/execution26/CMakeLists.txt index bcc11722..6edb36a2 100644 --- a/src/beman/execution26/CMakeLists.txt +++ b/src/beman/execution26/CMakeLists.txt @@ -6,6 +6,11 @@ add_library(${TARGET_LIBRARY} STATIC) add_library(${TARGET_ALIAS} ALIAS ${TARGET_LIBRARY}) +if(CMAKE_BUILD_TYPE STREQUAL Debug) + target_link_libraries(${TARGET_LIBRARY} PUBLIC $) + target_link_libraries(${TARGET_LIBRARY} PUBLIC $) +endif() + include(CMakePrintHelpers) cmake_print_variables(TARGET_ALIAS TARGET_LIBRARY TARGET_PREFIX PROJECT_SOURCE_DIR)