Skip to content

Commit

Permalink
Try to optimize CI sanitizer checks (#80)
Browse files Browse the repository at this point in the history
* Try to optimize CI sanitizer checks

* Add package_project cmake moduels

* Prevent to set sanitizer from Makefile

* Disable msan for now

* Build all presets on Windows too

* cleanup
  • Loading branch information
ClausKlein authored Nov 15, 2024
1 parent bc6a99a commit b8b689b
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 48 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ on:
paths:
- "include/**"
- "src/**"
- "test/**"
- "tests/**"
- "examples/**"
- "cmake/**"
- "Makefile"
- "CMakePresets.json"
Expand All @@ -20,7 +21,8 @@ on:
paths:
- "include/**"
- "src/**"
- "test/**"
- "tests/**"
- "examples/**"
- "cmake/**"
- "Makefile"
- "CMakePresets.json"
Expand Down Expand Up @@ -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
10 changes: 6 additions & 4 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ on:
paths:
- "include/**"
- "src/**"
- "test/**"
- "tests/**"
- "examples/**"
- "cmake/**"
- "Makefile"
- "CMakePresets.json"
Expand All @@ -20,7 +21,8 @@ on:
paths:
- "include/**"
- "src/**"
- "test/**"
- "tests/**"
- "examples/**"
- "cmake/**"
- "Makefile"
- "CMakePresets.json"
Expand Down Expand Up @@ -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 }}
Expand All @@ -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
19 changes: 10 additions & 9 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ on:
paths:
- "include/**"
- "src/**"
- "test/**"
- "tests/**"
- "examples/**"
- "cmake/**"
- "CMakePresets.json"
- "CMakeLists.txt"
Expand All @@ -19,7 +20,8 @@ on:
paths:
- "include/**"
- "src/**"
- "test/**"
- "tests/**"
- "examples/**"
- "cmake/**"
- "CMakePresets.json"
- "CMakeLists.txt"
Expand All @@ -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]

Expand All @@ -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 }}
58 changes: 54 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand All @@ -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)
Expand Down Expand Up @@ -50,4 +99,5 @@ install(
DESTINATION ${INSTALL_CONFIGDIR}
)

set(CPACK_GENERATOR TGZ)
include(CPack)
54 changes: 34 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 ?=
Expand All @@ -27,34 +28,40 @@ 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)
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
Expand All @@ -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)
Expand Down
6 changes: 2 additions & 4 deletions cmake/CMakeDarwinPresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
3 changes: 1 addition & 2 deletions cmake/CMakeLinuxPresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 1 addition & 2 deletions cmake/CMakeWindowsPresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion include/beman/execution26/detail/schedule_from.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Scheduler>()),
receiver_t{nullptr}));
};
}
explicit state_type(Scheduler& sch, Receiver& receiver) noexcept(nothrow())
: state_base<Receiver, Variant>{receiver},
op_state(::beman::execution26::connect(::beman::execution26::schedule(sch), receiver_t{this})) {}
Expand Down
5 changes: 5 additions & 0 deletions src/beman/execution26/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 $<BUILD_INTERFACE:${TARGET_LIBRARY}_project_options>)
target_link_libraries(${TARGET_LIBRARY} PUBLIC $<BUILD_INTERFACE:${TARGET_LIBRARY}_project_warnings>)
endif()

include(CMakePrintHelpers)
cmake_print_variables(TARGET_ALIAS TARGET_LIBRARY TARGET_PREFIX PROJECT_SOURCE_DIR)

Expand Down

0 comments on commit b8b689b

Please sign in to comment.