first commit
This commit is contained in:
commit
3413c94f8d
194
.github/workflows/ci.yml
vendored
Normal file
194
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
name: Continuous Integration
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with: { python-version: "3.8" }
|
||||||
|
|
||||||
|
- name: Install codespell
|
||||||
|
run: pip3 install codespell
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: cmake -D FORMAT_COMMAND=clang-format-14 -P cmake/lint.cmake
|
||||||
|
|
||||||
|
- name: Spell check
|
||||||
|
if: always()
|
||||||
|
run: cmake -P cmake/spell.cmake
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
needs: [lint]
|
||||||
|
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
# To enable coverage, delete the last line from the conditional below and
|
||||||
|
# edit the "<name>" placeholder to your GitHub name.
|
||||||
|
# If you do not wish to use codecov, then simply delete this job from the
|
||||||
|
# workflow.
|
||||||
|
if: github.repository_owner == '<name>'
|
||||||
|
&& false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install LCov
|
||||||
|
run: sudo apt-get update -q
|
||||||
|
&& sudo apt-get install lcov -q -y
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: cmake --preset=ci-coverage
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build/coverage -j 2
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
working-directory: build/coverage
|
||||||
|
run: ctest --output-on-failure --no-tests=error -j 2
|
||||||
|
|
||||||
|
- name: Process coverage info
|
||||||
|
run: cmake --build build/coverage -t coverage
|
||||||
|
|
||||||
|
- name: Submit to codecov.io
|
||||||
|
uses: codecov/codecov-action@v4
|
||||||
|
with:
|
||||||
|
file: build/coverage/coverage.info
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
|
sanitize:
|
||||||
|
needs: [lint]
|
||||||
|
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
env: { CXX: clang++-14 }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: cmake --preset=ci-sanitize
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build/sanitize -j 2
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
working-directory: build/sanitize
|
||||||
|
env:
|
||||||
|
ASAN_OPTIONS: "strict_string_checks=1:\
|
||||||
|
detect_stack_use_after_return=1:\
|
||||||
|
check_initialization_order=1:\
|
||||||
|
strict_init_order=1:\
|
||||||
|
detect_leaks=1:\
|
||||||
|
halt_on_error=1"
|
||||||
|
UBSAN_OPTIONS: "print_stacktrace=1:\
|
||||||
|
halt_on_error=1"
|
||||||
|
run: ctest --output-on-failure --no-tests=error -j 2
|
||||||
|
|
||||||
|
test:
|
||||||
|
needs: [lint]
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [macos-12, ubuntu-22.04, windows-2022]
|
||||||
|
|
||||||
|
type: [shared, static]
|
||||||
|
|
||||||
|
include:
|
||||||
|
- { type: shared, shared: YES }
|
||||||
|
- { type: static, shared: NO }
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install static analyzers
|
||||||
|
if: matrix.os == 'ubuntu-22.04'
|
||||||
|
run: >-
|
||||||
|
sudo apt-get install clang-tidy-14 cppcheck -y -q
|
||||||
|
|
||||||
|
sudo update-alternatives --install
|
||||||
|
/usr/bin/clang-tidy clang-tidy
|
||||||
|
/usr/bin/clang-tidy-14 140
|
||||||
|
|
||||||
|
- name: Setup MultiToolTask
|
||||||
|
if: matrix.os == 'windows-2022'
|
||||||
|
run: |
|
||||||
|
Add-Content "$env:GITHUB_ENV" 'UseMultiToolTask=true'
|
||||||
|
Add-Content "$env:GITHUB_ENV" 'EnforceProcessCountAcrossBuilds=true'
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
shell: pwsh
|
||||||
|
run: cmake "--preset=ci-$("${{ matrix.os }}".split("-")[0])"
|
||||||
|
-D BUILD_SHARED_LIBS=${{ matrix.shared }}
|
||||||
|
|
||||||
|
- name: Setup PATH
|
||||||
|
if: matrix.os == 'windows-2022' && matrix.type == 'shared'
|
||||||
|
run: Add-Content "$env:GITHUB_PATH" "$(Get-Location)\build\Release"
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --config Release -j 2
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: cmake --install build --config Release --prefix prefix
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
working-directory: build
|
||||||
|
run: ctest --output-on-failure --no-tests=error -C Release -j 2
|
||||||
|
|
||||||
|
docs:
|
||||||
|
# Deploy docs only when builds succeed
|
||||||
|
needs: [sanitize, test]
|
||||||
|
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
# To enable, first you have to create an orphaned gh-pages branch:
|
||||||
|
#
|
||||||
|
# git switch --orphan gh-pages
|
||||||
|
# git commit --allow-empty -m "Initial commit"
|
||||||
|
# git push -u origin gh-pages
|
||||||
|
#
|
||||||
|
# Edit the <name> placeholder below to your GitHub name, so this action
|
||||||
|
# runs only in your repository and no one else's fork. After these, delete
|
||||||
|
# this comment and the last line in the conditional below.
|
||||||
|
# If you do not wish to use GitHub Pages for deploying documentation, then
|
||||||
|
# simply delete this job similarly to the coverage one.
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
&& github.event_name == 'push'
|
||||||
|
&& github.repository_owner == '<name>'
|
||||||
|
&& false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with: { python-version: "3.8" }
|
||||||
|
|
||||||
|
- name: Install m.css dependencies
|
||||||
|
run: pip3 install jinja2 Pygments
|
||||||
|
|
||||||
|
- name: Install Doxygen
|
||||||
|
run: sudo apt-get update -q
|
||||||
|
&& sudo apt-get install doxygen -q -y
|
||||||
|
|
||||||
|
- name: Build docs
|
||||||
|
run: cmake "-DPROJECT_SOURCE_DIR=$PWD" "-DPROJECT_BINARY_DIR=$PWD/build"
|
||||||
|
-P cmake/docs-ci.cmake
|
||||||
|
|
||||||
|
- name: Deploy docs
|
||||||
|
uses: peaceiris/actions-gh-pages@v4
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: build/docs/html
|
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
**/.DS_Store
|
||||||
|
.idea/
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
build/
|
||||||
|
cmake-build-*/
|
||||||
|
prefix/
|
||||||
|
.clangd
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeUserPresets.json
|
||||||
|
compile_commands.json
|
||||||
|
env.bat
|
||||||
|
env.ps1
|
82
CMakeLists.txt
Normal file
82
CMakeLists.txt
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
include(cmake/prelude.cmake)
|
||||||
|
|
||||||
|
project(
|
||||||
|
nix-gcc-multi-issue
|
||||||
|
VERSION 0.1.0
|
||||||
|
DESCRIPTION "Short description"
|
||||||
|
HOMEPAGE_URL "https://example.com/"
|
||||||
|
LANGUAGES CXX
|
||||||
|
)
|
||||||
|
|
||||||
|
include(cmake/project-is-top-level.cmake)
|
||||||
|
include(cmake/variables.cmake)
|
||||||
|
|
||||||
|
# ---- Declare library ----
|
||||||
|
# build as 32-bit library
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
nix-gcc-multi-issue_nix-gcc-multi-issue
|
||||||
|
SHARED
|
||||||
|
source/nix-gcc-multi-issue.cpp
|
||||||
|
)
|
||||||
|
add_library(nix-gcc-multi-issue::nix-gcc-multi-issue ALIAS nix-gcc-multi-issue_nix-gcc-multi-issue)
|
||||||
|
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
generate_export_header(
|
||||||
|
nix-gcc-multi-issue_nix-gcc-multi-issue
|
||||||
|
BASE_NAME nix-gcc-multi-issue
|
||||||
|
EXPORT_FILE_NAME export/nix-gcc-multi-issue/nix-gcc-multi-issue_export.hpp
|
||||||
|
CUSTOM_CONTENT_FROM_VARIABLE pragma_suppress_c4251
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
|
target_compile_definitions(nix-gcc-multi-issue_nix-gcc-multi-issue PUBLIC NIX_GCC_MULTI_ISSUE_STATIC_DEFINE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
nix-gcc-multi-issue_nix-gcc-multi-issue PROPERTIES
|
||||||
|
CXX_VISIBILITY_PRESET hidden
|
||||||
|
VISIBILITY_INLINES_HIDDEN YES
|
||||||
|
VERSION "${PROJECT_VERSION}"
|
||||||
|
SOVERSION "${PROJECT_VERSION_MAJOR}"
|
||||||
|
EXPORT_NAME nix-gcc-multi-issue
|
||||||
|
OUTPUT_NAME nix-gcc-multi-issue
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
nix-gcc-multi-issue_nix-gcc-multi-issue ${warning_guard}
|
||||||
|
PUBLIC
|
||||||
|
"\$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
nix-gcc-multi-issue_nix-gcc-multi-issue SYSTEM
|
||||||
|
PUBLIC
|
||||||
|
"\$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/export>"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_features(nix-gcc-multi-issue_nix-gcc-multi-issue PUBLIC cxx_std_17)
|
||||||
|
|
||||||
|
# ---- Install rules ----
|
||||||
|
|
||||||
|
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||||
|
include(cmake/install-rules.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ---- Developer mode ----
|
||||||
|
|
||||||
|
if(NOT nix-gcc-multi-issue_DEVELOPER_MODE)
|
||||||
|
return()
|
||||||
|
elseif(NOT PROJECT_IS_TOP_LEVEL)
|
||||||
|
message(
|
||||||
|
AUTHOR_WARNING
|
||||||
|
"Developer mode is intended for developers of nix-gcc-multi-issue"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(cmake/dev-mode.cmake)
|
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# nix-gcc-multi-issue
|
||||||
|
|
||||||
|
This is the nix-gcc-multi-issue project.
|
||||||
|
|
||||||
|
# Building and installing
|
||||||
|
|
||||||
|
See the [BUILDING](BUILDING.md) document.
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
See the [CONTRIBUTING](CONTRIBUTING.md) document.
|
||||||
|
|
||||||
|
# Licensing
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Please go to https://choosealicense.com/licenses/ and choose a license that
|
||||||
|
fits your needs. The recommended license for a project of this type is the
|
||||||
|
Boost Software License 1.0.
|
||||||
|
-->
|
15
build.sh
Executable file
15
build.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
[ -z $CONFIG ] && config=Release || config="$CONFIG"
|
||||||
|
|
||||||
|
if [ "$SKIP_CMAKE" != "true" ]; then
|
||||||
|
cmake \
|
||||||
|
-S . \
|
||||||
|
-B build \
|
||||||
|
-G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=$config
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmake \
|
||||||
|
--build build \
|
||||||
|
--config $config \
|
||||||
|
--parallel $(nproc)
|
33
cmake/coverage.cmake
Normal file
33
cmake/coverage.cmake
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# ---- Variables ----
|
||||||
|
|
||||||
|
# We use variables separate from what CTest uses, because those have
|
||||||
|
# customization issues
|
||||||
|
set(
|
||||||
|
COVERAGE_TRACE_COMMAND
|
||||||
|
lcov -c -q
|
||||||
|
-o "${PROJECT_BINARY_DIR}/coverage.info"
|
||||||
|
-d "${PROJECT_BINARY_DIR}"
|
||||||
|
--include "${PROJECT_SOURCE_DIR}/*"
|
||||||
|
CACHE STRING
|
||||||
|
"; separated command to generate a trace for the 'coverage' target"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(
|
||||||
|
COVERAGE_HTML_COMMAND
|
||||||
|
genhtml --legend -f -q
|
||||||
|
"${PROJECT_BINARY_DIR}/coverage.info"
|
||||||
|
-p "${PROJECT_SOURCE_DIR}"
|
||||||
|
-o "${PROJECT_BINARY_DIR}/coverage_html"
|
||||||
|
CACHE STRING
|
||||||
|
"; separated command to generate an HTML report for the 'coverage' target"
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- Coverage target ----
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
coverage
|
||||||
|
COMMAND ${COVERAGE_TRACE_COMMAND}
|
||||||
|
COMMAND ${COVERAGE_HTML_COMMAND}
|
||||||
|
COMMENT "Generating coverage report"
|
||||||
|
VERBATIM
|
||||||
|
)
|
21
cmake/dev-mode.cmake
Normal file
21
cmake/dev-mode.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
include(cmake/folders.cmake)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(BUILD_MCSS_DOCS "Build documentation using Doxygen and m.css" OFF)
|
||||||
|
if(BUILD_MCSS_DOCS)
|
||||||
|
include(cmake/docs.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_COVERAGE "Enable coverage support separate from CTest's" OFF)
|
||||||
|
if(ENABLE_COVERAGE)
|
||||||
|
include(cmake/coverage.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(cmake/lint-targets.cmake)
|
||||||
|
include(cmake/spell-targets.cmake)
|
||||||
|
|
||||||
|
add_folders(Project)
|
112
cmake/docs-ci.cmake
Normal file
112
cmake/docs-ci.cmake
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
foreach(var IN ITEMS PROJECT_BINARY_DIR PROJECT_SOURCE_DIR)
|
||||||
|
if(NOT DEFINED "${var}")
|
||||||
|
message(FATAL_ERROR "${var} must be defined")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(bin "${PROJECT_BINARY_DIR}")
|
||||||
|
set(src "${PROJECT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
# ---- Dependencies ----
|
||||||
|
|
||||||
|
set(mcss_SOURCE_DIR "${bin}/docs/.ci")
|
||||||
|
if(NOT IS_DIRECTORY "${mcss_SOURCE_DIR}")
|
||||||
|
file(MAKE_DIRECTORY "${mcss_SOURCE_DIR}")
|
||||||
|
file(
|
||||||
|
DOWNLOAD
|
||||||
|
https://github.com/friendlyanon/m.css/releases/download/release-1/mcss.zip
|
||||||
|
"${mcss_SOURCE_DIR}/mcss.zip"
|
||||||
|
STATUS status
|
||||||
|
EXPECTED_MD5 00cd2757ebafb9bcba7f5d399b3bec7f
|
||||||
|
)
|
||||||
|
if(NOT status MATCHES "^0;")
|
||||||
|
message(FATAL_ERROR "Download failed with ${status}")
|
||||||
|
endif()
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E tar xf mcss.zip
|
||||||
|
WORKING_DIRECTORY "${mcss_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
if(NOT result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "Extraction failed with ${result}")
|
||||||
|
endif()
|
||||||
|
file(REMOVE "${mcss_SOURCE_DIR}/mcss.zip")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_program(Python3_EXECUTABLE NAMES python3 python)
|
||||||
|
if(NOT Python3_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "Python executable was not found")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ---- Process project() call in CMakeLists.txt ----
|
||||||
|
|
||||||
|
file(READ "${src}/CMakeLists.txt" content)
|
||||||
|
|
||||||
|
string(FIND "${content}" "project(" index)
|
||||||
|
if(index EQUAL "-1")
|
||||||
|
message(FATAL_ERROR "Could not find \"project(\"")
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${content}" "${index}" -1 content)
|
||||||
|
|
||||||
|
string(FIND "${content}" "\n)\n" index)
|
||||||
|
if(index EQUAL "-1")
|
||||||
|
message(FATAL_ERROR "Could not find \"\\n)\\n\"")
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${content}" 0 "${index}" content)
|
||||||
|
|
||||||
|
file(WRITE "${bin}/docs-ci.project.cmake" "docs_${content}\n)\n")
|
||||||
|
|
||||||
|
macro(list_pop_front list out)
|
||||||
|
list(GET "${list}" 0 "${out}")
|
||||||
|
list(REMOVE_AT "${list}" 0)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
function(docs_project name)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 1 "" "" "VERSION;DESCRIPTION;HOMEPAGE_URL" LANGUAGES)
|
||||||
|
set(PROJECT_NAME "${name}" PARENT_SCOPE)
|
||||||
|
if(DEFINED _VERSION)
|
||||||
|
set(PROJECT_VERSION "${_VERSION}" PARENT_SCOPE)
|
||||||
|
string(REGEX MATCH "^[0-9]+(\\.[0-9]+)*" versions "${_VERSION}")
|
||||||
|
string(REPLACE . ";" versions "${versions}")
|
||||||
|
set(suffixes MAJOR MINOR PATCH TWEAK)
|
||||||
|
while(NOT versions STREQUAL "" AND NOT suffixes STREQUAL "")
|
||||||
|
list_pop_front(versions version)
|
||||||
|
list_pop_front(suffixes suffix)
|
||||||
|
set("PROJECT_VERSION_${suffix}" "${version}" PARENT_SCOPE)
|
||||||
|
endwhile()
|
||||||
|
endif()
|
||||||
|
if(DEFINED _DESCRIPTION)
|
||||||
|
set(PROJECT_DESCRIPTION "${_DESCRIPTION}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
if(DEFINED _HOMEPAGE_URL)
|
||||||
|
set(PROJECT_HOMEPAGE_URL "${_HOMEPAGE_URL}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
include("${bin}/docs-ci.project.cmake")
|
||||||
|
|
||||||
|
# ---- Generate docs ----
|
||||||
|
|
||||||
|
if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY)
|
||||||
|
set(DOXYGEN_OUTPUT_DIRECTORY "${bin}/docs")
|
||||||
|
endif()
|
||||||
|
set(out "${DOXYGEN_OUTPUT_DIRECTORY}")
|
||||||
|
|
||||||
|
foreach(file IN ITEMS Doxyfile conf.py)
|
||||||
|
configure_file("${src}/docs/${file}.in" "${bin}/docs/${file}" @ONLY)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(mcss_script "${mcss_SOURCE_DIR}/documentation/doxygen.py")
|
||||||
|
set(config "${bin}/docs/conf.py")
|
||||||
|
|
||||||
|
file(REMOVE_RECURSE "${out}/html" "${out}/xml")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${Python3_EXECUTABLE}" "${mcss_script}" "${config}"
|
||||||
|
WORKING_DIRECTORY "${bin}/docs"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
if(NOT result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "m.css returned with ${result}")
|
||||||
|
endif()
|
46
cmake/docs.cmake
Normal file
46
cmake/docs.cmake
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# ---- Dependencies ----
|
||||||
|
|
||||||
|
set(extract_timestamps "")
|
||||||
|
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
|
||||||
|
set(extract_timestamps DOWNLOAD_EXTRACT_TIMESTAMP YES)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
mcss URL
|
||||||
|
https://github.com/friendlyanon/m.css/releases/download/release-1/mcss.zip
|
||||||
|
URL_MD5 00cd2757ebafb9bcba7f5d399b3bec7f
|
||||||
|
SOURCE_DIR "${PROJECT_BINARY_DIR}/mcss"
|
||||||
|
UPDATE_DISCONNECTED YES
|
||||||
|
${extract_timestamps}
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(mcss)
|
||||||
|
|
||||||
|
find_package(Python3 3.6 REQUIRED)
|
||||||
|
|
||||||
|
# ---- Declare documentation target ----
|
||||||
|
|
||||||
|
set(
|
||||||
|
DOXYGEN_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/docs"
|
||||||
|
CACHE PATH "Path for the generated Doxygen documentation"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(working_dir "${PROJECT_BINARY_DIR}/docs")
|
||||||
|
|
||||||
|
foreach(file IN ITEMS Doxyfile conf.py)
|
||||||
|
configure_file("docs/${file}.in" "${working_dir}/${file}" @ONLY)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(mcss_script "${mcss_SOURCE_DIR}/documentation/doxygen.py")
|
||||||
|
set(config "${working_dir}/conf.py")
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
docs
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||||
|
"${DOXYGEN_OUTPUT_DIRECTORY}/html"
|
||||||
|
"${DOXYGEN_OUTPUT_DIRECTORY}/xml"
|
||||||
|
COMMAND "${Python3_EXECUTABLE}" "${mcss_script}" "${config}"
|
||||||
|
COMMENT "Building documentation using Doxygen and m.css"
|
||||||
|
WORKING_DIRECTORY "${working_dir}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
21
cmake/folders.cmake
Normal file
21
cmake/folders.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS YES)
|
||||||
|
|
||||||
|
# Call this function at the end of a directory scope to assign a folder to
|
||||||
|
# targets created in that directory. Utility targets will be assigned to the
|
||||||
|
# UtilityTargets folder, otherwise to the ${name}Targets folder. If a target
|
||||||
|
# already has a folder assigned, then that target will be skipped.
|
||||||
|
function(add_folders name)
|
||||||
|
get_property(targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
|
||||||
|
foreach(target IN LISTS targets)
|
||||||
|
get_property(folder TARGET "${target}" PROPERTY FOLDER)
|
||||||
|
if(DEFINED folder)
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
set(folder Utility)
|
||||||
|
get_property(type TARGET "${target}" PROPERTY TYPE)
|
||||||
|
if(NOT type STREQUAL "UTILITY")
|
||||||
|
set(folder "${name}")
|
||||||
|
endif()
|
||||||
|
set_property(TARGET "${target}" PROPERTY FOLDER "${folder}Targets")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
1
cmake/install-config.cmake
Normal file
1
cmake/install-config.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/nix-gcc-multi-issueTargets.cmake")
|
72
cmake/install-rules.cmake
Normal file
72
cmake/install-rules.cmake
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
set(
|
||||||
|
CMAKE_INSTALL_INCLUDEDIR "include/nix-gcc-multi-issue-${PROJECT_VERSION}"
|
||||||
|
CACHE STRING ""
|
||||||
|
)
|
||||||
|
set_property(CACHE CMAKE_INSTALL_INCLUDEDIR PROPERTY TYPE PATH)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# find_package(<package>) call for consumers to find this project
|
||||||
|
set(package nix-gcc-multi-issue)
|
||||||
|
|
||||||
|
install(
|
||||||
|
DIRECTORY
|
||||||
|
include/
|
||||||
|
"${PROJECT_BINARY_DIR}/export/"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
COMPONENT nix-gcc-multi-issue_Development
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS nix-gcc-multi-issue_nix-gcc-multi-issue
|
||||||
|
EXPORT nix-gcc-multi-issueTargets
|
||||||
|
RUNTIME #
|
||||||
|
COMPONENT nix-gcc-multi-issue_Runtime
|
||||||
|
LIBRARY #
|
||||||
|
COMPONENT nix-gcc-multi-issue_Runtime
|
||||||
|
NAMELINK_COMPONENT nix-gcc-multi-issue_Development
|
||||||
|
ARCHIVE #
|
||||||
|
COMPONENT nix-gcc-multi-issue_Development
|
||||||
|
INCLUDES #
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${package}ConfigVersion.cmake"
|
||||||
|
COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
# Allow package maintainers to freely override the path for the configs
|
||||||
|
set(
|
||||||
|
nix-gcc-multi-issue_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${package}"
|
||||||
|
CACHE STRING "CMake package config location relative to the install prefix"
|
||||||
|
)
|
||||||
|
set_property(CACHE nix-gcc-multi-issue_INSTALL_CMAKEDIR PROPERTY TYPE PATH)
|
||||||
|
mark_as_advanced(nix-gcc-multi-issue_INSTALL_CMAKEDIR)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES cmake/install-config.cmake
|
||||||
|
DESTINATION "${nix-gcc-multi-issue_INSTALL_CMAKEDIR}"
|
||||||
|
RENAME "${package}Config.cmake"
|
||||||
|
COMPONENT nix-gcc-multi-issue_Development
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES "${PROJECT_BINARY_DIR}/${package}ConfigVersion.cmake"
|
||||||
|
DESTINATION "${nix-gcc-multi-issue_INSTALL_CMAKEDIR}"
|
||||||
|
COMPONENT nix-gcc-multi-issue_Development
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT nix-gcc-multi-issueTargets
|
||||||
|
NAMESPACE nix-gcc-multi-issue::
|
||||||
|
DESTINATION "${nix-gcc-multi-issue_INSTALL_CMAKEDIR}"
|
||||||
|
COMPONENT nix-gcc-multi-issue_Development
|
||||||
|
)
|
||||||
|
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
include(CPack)
|
||||||
|
endif()
|
33
cmake/lint-targets.cmake
Normal file
33
cmake/lint-targets.cmake
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
set(
|
||||||
|
FORMAT_PATTERNS
|
||||||
|
source/*.cpp source/*.hpp
|
||||||
|
include/*.hpp
|
||||||
|
test/*.cpp test/*.hpp
|
||||||
|
CACHE STRING
|
||||||
|
"; separated patterns relative to the project source dir to format"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(FORMAT_COMMAND clang-format CACHE STRING "Formatter to use")
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
format-check
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-D "FORMAT_COMMAND=${FORMAT_COMMAND}"
|
||||||
|
-D "PATTERNS=${FORMAT_PATTERNS}"
|
||||||
|
-P "${PROJECT_SOURCE_DIR}/cmake/lint.cmake"
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
|
COMMENT "Linting the code"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
format-fix
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-D "FORMAT_COMMAND=${FORMAT_COMMAND}"
|
||||||
|
-D "PATTERNS=${FORMAT_PATTERNS}"
|
||||||
|
-D FIX=YES
|
||||||
|
-P "${PROJECT_SOURCE_DIR}/cmake/lint.cmake"
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
|
COMMENT "Fixing the code"
|
||||||
|
VERBATIM
|
||||||
|
)
|
51
cmake/lint.cmake
Normal file
51
cmake/lint.cmake
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
macro(default name)
|
||||||
|
if(NOT DEFINED "${name}")
|
||||||
|
set("${name}" "${ARGN}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
default(FORMAT_COMMAND clang-format)
|
||||||
|
default(
|
||||||
|
PATTERNS
|
||||||
|
source/*.cpp source/*.hpp
|
||||||
|
include/*.hpp
|
||||||
|
test/*.cpp test/*.hpp
|
||||||
|
)
|
||||||
|
default(FIX NO)
|
||||||
|
|
||||||
|
set(flag --output-replacements-xml)
|
||||||
|
set(args OUTPUT_VARIABLE output)
|
||||||
|
if(FIX)
|
||||||
|
set(flag -i)
|
||||||
|
set(args "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(GLOB_RECURSE files ${PATTERNS})
|
||||||
|
set(badly_formatted "")
|
||||||
|
set(output "")
|
||||||
|
string(LENGTH "${CMAKE_SOURCE_DIR}/" path_prefix_length)
|
||||||
|
|
||||||
|
foreach(file IN LISTS files)
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${FORMAT_COMMAND}" --style=file "${flag}" "${file}"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
${args}
|
||||||
|
)
|
||||||
|
if(NOT result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "'${file}': formatter returned with ${result}")
|
||||||
|
endif()
|
||||||
|
if(NOT FIX AND output MATCHES "\n<replacement offset")
|
||||||
|
string(SUBSTRING "${file}" "${path_prefix_length}" -1 relative_file)
|
||||||
|
list(APPEND badly_formatted "${relative_file}")
|
||||||
|
endif()
|
||||||
|
set(output "")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(NOT badly_formatted STREQUAL "")
|
||||||
|
list(JOIN badly_formatted "\n" bad_list)
|
||||||
|
message("The following files are badly formatted:\n\n${bad_list}\n")
|
||||||
|
message(FATAL_ERROR "Run again with FIX=YES to fix these files.")
|
||||||
|
endif()
|
10
cmake/prelude.cmake
Normal file
10
cmake/prelude.cmake
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# ---- In-source guard ----
|
||||||
|
|
||||||
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"In-source builds are not supported. "
|
||||||
|
"Please read the BUILDING document before trying to build this project. "
|
||||||
|
"You may need to delete 'CMakeCache.txt' and 'CMakeFiles/' first."
|
||||||
|
)
|
||||||
|
endif()
|
6
cmake/project-is-top-level.cmake
Normal file
6
cmake/project-is-top-level.cmake
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# This variable is set by project() in CMake 3.21+
|
||||||
|
string(
|
||||||
|
COMPARE EQUAL
|
||||||
|
"${CMAKE_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}"
|
||||||
|
PROJECT_IS_TOP_LEVEL
|
||||||
|
)
|
22
cmake/spell-targets.cmake
Normal file
22
cmake/spell-targets.cmake
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
set(SPELL_COMMAND codespell CACHE STRING "Spell checker to use")
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
spell-check
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-D "SPELL_COMMAND=${SPELL_COMMAND}"
|
||||||
|
-P "${PROJECT_SOURCE_DIR}/cmake/spell.cmake"
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
|
COMMENT "Checking spelling"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
spell-fix
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-D "SPELL_COMMAND=${SPELL_COMMAND}"
|
||||||
|
-D FIX=YES
|
||||||
|
-P "${PROJECT_SOURCE_DIR}/cmake/spell.cmake"
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
|
COMMENT "Fixing spelling errors"
|
||||||
|
VERBATIM
|
||||||
|
)
|
29
cmake/spell.cmake
Normal file
29
cmake/spell.cmake
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
macro(default name)
|
||||||
|
if(NOT DEFINED "${name}")
|
||||||
|
set("${name}" "${ARGN}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
default(SPELL_COMMAND codespell)
|
||||||
|
default(FIX NO)
|
||||||
|
|
||||||
|
set(flag "")
|
||||||
|
if(FIX)
|
||||||
|
set(flag -w)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${SPELL_COMMAND}" ${flag}
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
|
||||||
|
if(result EQUAL "65")
|
||||||
|
message(FATAL_ERROR "Run again with FIX=YES to fix these errors.")
|
||||||
|
elseif(result EQUAL "64")
|
||||||
|
message(FATAL_ERROR "Spell checker printed the usage info. Bad arguments?")
|
||||||
|
elseif(NOT result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "Spell checker returned with ${result}")
|
||||||
|
endif()
|
41
cmake/variables.cmake
Normal file
41
cmake/variables.cmake
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# ---- Developer mode ----
|
||||||
|
|
||||||
|
# Developer mode enables targets and code paths in the CMake scripts that are
|
||||||
|
# only relevant for the developer(s) of nix-gcc-multi-issue
|
||||||
|
# Targets necessary to build the project must be provided unconditionally, so
|
||||||
|
# consumers can trivially build and package the project
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
option(nix-gcc-multi-issue_DEVELOPER_MODE "Enable developer mode" OFF)
|
||||||
|
option(BUILD_SHARED_LIBS "Build shared libs." OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ---- Suppress C4251 on Windows ----
|
||||||
|
|
||||||
|
# Please see include/nix-gcc-multi-issue/nix-gcc-multi-issue.hpp for more details
|
||||||
|
set(pragma_suppress_c4251 "
|
||||||
|
/* This needs to suppress only for MSVC */
|
||||||
|
#if defined(_MSC_VER) && !defined(__ICL)
|
||||||
|
# define NIX_GCC_MULTI_ISSUE_SUPPRESS_C4251 _Pragma(\"warning(suppress:4251)\")
|
||||||
|
#else
|
||||||
|
# define NIX_GCC_MULTI_ISSUE_SUPPRESS_C4251
|
||||||
|
#endif
|
||||||
|
")
|
||||||
|
|
||||||
|
# ---- Warning guard ----
|
||||||
|
|
||||||
|
# target_include_directories with the SYSTEM modifier will request the compiler
|
||||||
|
# to omit warnings from the provided paths, if the compiler supports that
|
||||||
|
# This is to provide a user experience similar to find_package when
|
||||||
|
# add_subdirectory or FetchContent is used to consume this project
|
||||||
|
set(warning_guard "")
|
||||||
|
if(NOT PROJECT_IS_TOP_LEVEL)
|
||||||
|
option(
|
||||||
|
nix-gcc-multi-issue_INCLUDES_WITH_SYSTEM
|
||||||
|
"Use SYSTEM modifier for nix-gcc-multi-issue's includes, disabling warnings"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
mark_as_advanced(nix-gcc-multi-issue_INCLUDES_WITH_SYSTEM)
|
||||||
|
if(nix-gcc-multi-issue_INCLUDES_WITH_SYSTEM)
|
||||||
|
set(warning_guard SYSTEM)
|
||||||
|
endif()
|
||||||
|
endif()
|
48
flake.lock
Normal file
48
flake.lock
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1714641030,
|
||||||
|
"narHash": "sha256-yzcRNDoyVP7+SCNX0wmuDju1NUCt8Dz9+lyUXEI0dbI=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "e5d10a24b66c3ea8f150e47dfdb0416ab7c3390e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1715534503,
|
||||||
|
"narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
31
flake.nix
Normal file
31
flake.nix
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-parts = {
|
||||||
|
url = "github:hercules-ci/flake-parts";
|
||||||
|
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
inputs@{ flake-parts
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
];
|
||||||
|
|
||||||
|
perSystem = { pkgs, lib, system, self', ... }: {
|
||||||
|
devShells.default = pkgs.mkShell.override { stdenv = pkgs.multiStdenv; }
|
||||||
|
(with pkgs;
|
||||||
|
{
|
||||||
|
packages = [
|
||||||
|
pkg-config
|
||||||
|
cmake
|
||||||
|
ninja
|
||||||
|
];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
70
include/nix-gcc-multi-issue/nix-gcc-multi-issue.hpp
Normal file
70
include/nix-gcc-multi-issue/nix-gcc-multi-issue.hpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "nix-gcc-multi-issue/nix-gcc-multi-issue_export.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A note about the MSVC warning C4251:
|
||||||
|
* This warning should be suppressed for private data members of the project's
|
||||||
|
* exported classes, because there are too many ways to work around it and all
|
||||||
|
* involve some kind of trade-off (increased code complexity requiring more
|
||||||
|
* developer time, writing boilerplate code, longer compile times), but those
|
||||||
|
* solutions are very situational and solve things in slightly different ways,
|
||||||
|
* depending on the requirements of the project.
|
||||||
|
* That is to say, there is no general solution.
|
||||||
|
*
|
||||||
|
* What can be done instead is understand where issues could arise where this
|
||||||
|
* warning is spotting a legitimate bug. I will give the general description of
|
||||||
|
* this warning's cause and break it down to make it trivial to understand.
|
||||||
|
*
|
||||||
|
* C4251 is emitted when an exported class has a non-static data member of a
|
||||||
|
* non-exported class type.
|
||||||
|
*
|
||||||
|
* The exported class in our case is the class below (exported_class), which
|
||||||
|
* has a non-static data member (m_name) of a non-exported class type
|
||||||
|
* (std::string).
|
||||||
|
*
|
||||||
|
* The rationale here is that the user of the exported class could attempt to
|
||||||
|
* access (directly, or via an inline member function) a static data member or
|
||||||
|
* a non-inline member function of the data member, resulting in a linker
|
||||||
|
* error.
|
||||||
|
* Inline member function above means member functions that are defined (not
|
||||||
|
* declared) in the class definition.
|
||||||
|
*
|
||||||
|
* Since this exported class never makes these non-exported types available to
|
||||||
|
* the user, we can safely ignore this warning. It's fine if there are
|
||||||
|
* non-exported class types as private member variables, because they are only
|
||||||
|
* accessed by the members of the exported class itself.
|
||||||
|
*
|
||||||
|
* The name() method below returns a pointer to the stored null-terminated
|
||||||
|
* string as a fundamental type (char const), so this is safe to use anywhere.
|
||||||
|
* The only downside is that you can have dangling pointers if the pointer
|
||||||
|
* outlives the class instance which stored the string.
|
||||||
|
*
|
||||||
|
* Shared libraries are not easy, they need some discipline to get right, but
|
||||||
|
* they also solve some other problems that make them worth the time invested.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reports the name of the library
|
||||||
|
*
|
||||||
|
* Please see the note above for considerations when creating shared libraries.
|
||||||
|
*/
|
||||||
|
class NIX_GCC_MULTI_ISSUE_EXPORT exported_class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Initializes the name field to the name of the project
|
||||||
|
*/
|
||||||
|
exported_class();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a non-owning pointer to the string stored in this class
|
||||||
|
*/
|
||||||
|
auto name() const -> char const*;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NIX_GCC_MULTI_ISSUE_SUPPRESS_C4251
|
||||||
|
std::string m_name;
|
||||||
|
};
|
15
source/nix-gcc-multi-issue.cpp
Normal file
15
source/nix-gcc-multi-issue.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "nix-gcc-multi-issue/nix-gcc-multi-issue.hpp"
|
||||||
|
|
||||||
|
exported_class::exported_class()
|
||||||
|
: m_name {"nix-gcc-multi-issue"}
|
||||||
|
{
|
||||||
|
std::cout << "Hello, World!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto exported_class::name() const -> char const*
|
||||||
|
{
|
||||||
|
return m_name.c_str();
|
||||||
|
}
|
25
test/CMakeLists.txt
Normal file
25
test/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
project(nix-gcc-multi-issueTests LANGUAGES CXX)
|
||||||
|
|
||||||
|
include(../cmake/project-is-top-level.cmake)
|
||||||
|
include(../cmake/folders.cmake)
|
||||||
|
|
||||||
|
# ---- Dependencies ----
|
||||||
|
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
find_package(nix-gcc-multi-issue REQUIRED)
|
||||||
|
enable_testing()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ---- Tests ----
|
||||||
|
|
||||||
|
add_executable(nix-gcc-multi-issue_test source/nix-gcc-multi-issue_test.cpp)
|
||||||
|
target_link_libraries(nix-gcc-multi-issue_test PRIVATE nix-gcc-multi-issue::nix-gcc-multi-issue)
|
||||||
|
target_compile_features(nix-gcc-multi-issue_test PRIVATE cxx_std_17)
|
||||||
|
|
||||||
|
add_test(NAME nix-gcc-multi-issue_test COMMAND nix-gcc-multi-issue_test)
|
||||||
|
|
||||||
|
# ---- End-of-file commands ----
|
||||||
|
|
||||||
|
add_folders(Test)
|
10
test/source/nix-gcc-multi-issue_test.cpp
Normal file
10
test/source/nix-gcc-multi-issue_test.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "nix-gcc-multi-issue/nix-gcc-multi-issue.hpp"
|
||||||
|
|
||||||
|
auto main() -> int
|
||||||
|
{
|
||||||
|
auto const exported = exported_class {};
|
||||||
|
|
||||||
|
return std::string("nix-gcc-multi-issue") == exported.name() ? 0 : 1;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user