Skip to content

Commit

Permalink
Merge branch 'master' into test_package_with_modules
Browse files Browse the repository at this point in the history
  • Loading branch information
mpusz authored Apr 17, 2024
2 parents c255e13 + 8e50eae commit 6cea16b
Show file tree
Hide file tree
Showing 28 changed files with 502 additions and 221 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-conan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,13 @@ jobs:
sed -i.backup '/^\[settings\]$/,/^\[/ s/^compiler.cppstd=.*/compiler.cppstd=${{ matrix.std }}/' ~/.conan2/profiles/default
sed -i.backup '/^\[settings\]$/,/^\[/ s/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/default
conan profile show -pr default
- run: echo "use_fmtlib=$([ "${{ matrix.formatting }}" == "fmtlib" ] && echo "True" || echo "False")" >> $GITHUB_ENV
- run: echo "std_format=$([ "${{ matrix.formatting }}" == "std::format" ] && echo "True" || echo "False")" >> $GITHUB_ENV
- name: Create Conan package
shell: bash
run: |
conan create . --user mpusz --channel ${CHANNEL} --lockfile-out=package.lock \
-b mp-units/* -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" \
-c user.mp-units.build:all=True -o cxx_modules=${{ matrix.config.cxx_modules }} -o use_fmtlib=${{ env.use_fmtlib }} ${{ matrix.config.conan-config }}
-c user.mp-units.build:all=True -o cxx_modules=${{ matrix.config.cxx_modules }} -o std_format=${{ env.std_format }} ${{ matrix.config.conan-config }}
- name: Obtain package reference
id: get-package-ref
shell: bash
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-test-package-cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,12 @@ jobs:
sed -i.backup '/^\[settings\]$/,/^\[/ s/^compiler.cppstd=.*/compiler.cppstd=${{ matrix.std }}/' ~/.conan2/profiles/default
sed -i.backup '/^\[settings\]$/,/^\[/ s/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/default
conan profile show -pr default
- run: echo "use_fmtlib=$([ "${{ matrix.formatting }}" == "fmtlib" ] && echo "True" || echo "False")" >> $GITHUB_ENV
- run: echo "std_format=$([ "${{ matrix.formatting }}" == "std::format" ] && echo "True" || echo "False")" >> $GITHUB_ENV
- name: Install Conan dependencies
shell: bash
run: |
conan install . -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" -c user.mp-units.build:all=False \
-o cxx_modules=${{ matrix.config.cxx_modules }} -o use_fmtlib=${{ env.use_fmtlib }}
-o cxx_modules=${{ matrix.config.cxx_modules }} -o std_format=${{ env.std_format }}
mv CMakeUserPresets.json src
- name: Configure mp-units CMake
if: matrix.config.compiler.type == 'VISUAL' || matrix.config.compiler.type == 'MSVC'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
conan profile detect --force
conan remote add artifactory https://mpusz.jfrog.io/artifactory/api/conan/conan-oss
mkdir _lgtm_build_dir && cd _lgtm_build_dir
conan build .. -s compiler.cppstd=20 -c user.mp-units.build:all=True -o use_fmtlib=True -b missing
conan build .. -s compiler.cppstd=20 -c user.mp-units.build:all=True -o std_format=False -b missing
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
Expand Down
32 changes: 16 additions & 16 deletions .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,47 +70,47 @@ tasks:
gp sync-await python-init
conan profile detect
conan config install $PWD/.gitpod/conan
conan install . -pr gcc12 -o use_fmtlib=True -b missing
conan install . -pr gcc12 -o use_fmtlib=True -b missing -s build_type=Debug
conan install . -pr gcc12 -o std_format=False -b missing
conan install . -pr gcc12 -o std_format=False -b missing -s build_type=Debug
gp sync-done conan-gcc12-20
conan install . -pr gcc13 -b missing
conan install . -pr gcc13 -b missing -s build_type=Debug
conan install . -pr gcc13 -o std_format=True -b missing
conan install . -pr gcc13 -o std_format=True -b missing -s build_type=Debug
gp sync-done conan-gcc13-20
conan install . -pr clang16 -o use_fmtlib=True -b missing
conan install . -pr clang16 -o use_fmtlib=True -b missing -s build_type=Debug
conan install . -pr clang16 -o std_format=False -b missing
conan install . -pr clang16 -o std_format=False -b missing -s build_type=Debug
gp sync-done conan-clang16-20
conan install . -pr clang17 -o cxx_modules=True -b missing
conan install . -pr clang17 -o cxx_modules=True -b missing -s build_type=Debug
conan install . -pr clang17 -o std_format=True -o cxx_modules=True -b missing
conan install . -pr clang17 -o std_format=True -o cxx_modules=True -b missing -s build_type=Debug
gp sync-done conan-clang17-20
conan remote login -p $ARTIFACTORY_TOKEN conan-gitpod-mp-units $ARTIFACTORY_USER
conan upload "*" -r conan-gitpod-mp-units -c
- name: gcc-12-20
init: |
gp sync-await conan-gcc12-20
source ${PYTHON_VENV}/bin/activate
conan build . -pr gcc12 -o use_fmtlib=True
conan build . -pr gcc12 -o use_fmtlib=True -s build_type=Debug
conan build . -pr gcc12 -o std_format=False
conan build . -pr gcc12 -o std_format=False -s build_type=Debug
echo "🛠️ gcc-12 pre-build done for C++20, header files, and libfmt! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
- name: gcc-13-20
init: |
gp sync-await conan-gcc13-20
source ${PYTHON_VENV}/bin/activate
conan build . -pr gcc13
conan build . -pr gcc13 -s build_type=Debug
conan build . -pr gcc13 -o std_format=True
conan build . -pr gcc13 -o std_format=True -s build_type=Debug
echo "🛠️ gcc-13 pre-build done for C++20 and header files! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
- name: clang-16-20
init: |
gp sync-await conan-clang16-20
source ${PYTHON_VENV}/bin/activate
conan build . -pr clang16 -o use_fmtlib=True
conan build . -pr clang16 -o use_fmtlib=True -s build_type=Debug
conan build . -pr clang16 -o std_format=False
conan build . -pr clang16 -o std_format=False -s build_type=Debug
echo "🛠️ clang-16 pre-build done for C++20, header files, and libfmt! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
- name: clang-17-20
init: |
gp sync-await conan-clang17-20
source ${PYTHON_VENV}/bin/activate
conan build . -pr clang17 -o cxx_modules=True
conan build . -pr clang17 -o cxx_modules=True -s build_type=Debug
conan build . -pr clang17 -o std_format=True -o cxx_modules=True
conan build . -pr clang17 -o std_format=True -o cxx_modules=True -s build_type=Debug
echo "🛠️ clang-17 pre-build done for C++20! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
- name: documentation
init: |
Expand Down
12 changes: 4 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

set(projectPrefix MP_UNITS_)

option(${projectPrefix}BUILD_LA "Build code depending on the linear algebra library" ON)
message(STATUS "${projectPrefix}BUILD_LA: ${${projectPrefix}BUILD_LA}")
option(${projectPrefix}DEV_BUILD_LA "Build code depending on the linear algebra library" ON)
message(STATUS "${projectPrefix}DEV_BUILD_LA: ${${projectPrefix}DEV_BUILD_LA}")

# make sure that the file is being used as an entry point
include(modern_project_structure)
Expand All @@ -43,20 +43,16 @@ include(warnings)
set_warnings()

# enable include-what-you-use
option(${projectPrefix}IWYU "Enables include-what-you-use" OFF)
option(${projectPrefix}DEV_IWYU "Enables include-what-you-use" OFF)

if(${projectPrefix}IWYU)
if(${projectPrefix}DEV_IWYU)
include(include-what-you-use)
enable_iwyu(
MAPPING_FILE "${PROJECT_SOURCE_DIR}/.mp-units.imp"
NO_FORWARD_DECLARATIONS QUOTED_INCLUDES_FIRST
MAX_LINE_LENGTH 120
NO_COMMENTS
)

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(${projectPrefix}AS_SYSTEM_HEADERS ON)
endif()
endif()

# enable_clang_tidy()
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Before submission, please remember to check if the code compiles fine on the sup
The CI will check it anyway but it is good to check at least some of the configurations before pushing changes.
Especially older compilers can be tricky as those do not support all the C++20 features well enough. The official
list of supported compilers can be always found in the
[Installation And Usage](https://mpusz.github.io/mp-units/latest/getting_started/installation_and_usage/#cpp-compiler-support)
[Installation And Usage](https://mpusz.github.io/mp-units/latest/getting_started/cpp_compiler_support)
chapter of our documentation.


Expand Down
167 changes: 124 additions & 43 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,20 @@

from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import can_run, check_min_cppstd
from conan.tools.build import can_run, default_cppstd, valid_min_cppstd
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import copy, load, rmdir

required_conan_version = ">=2.0.0"


def loose_lt_semver(v1, v2):
lv1 = [int(v) for v in v1.split(".")]
lv2 = [int(v) for v in v2.split(".")]
min_length = min(len(lv1), len(lv2))
return lv1[:min_length] < lv2[:min_length]


class MPUnitsConan(ConanFile):
name = "mp-units"
homepage = "https://github.com/mpusz/mp-units"
Expand All @@ -54,14 +61,18 @@ class MPUnitsConan(ConanFile):
url = "https://github.com/mpusz/mp-units"
settings = "os", "arch", "compiler", "build_type"
options = {
"cxx_modules": [True, False],
"use_fmtlib": [True, False],
"cxx_modules": ["auto", True, False],
"std_format": ["auto", True, False],
"string_view_ret": ["auto", True, False],
"no_crtp": ["auto", True, False],
}
default_options = {
"cxx_modules": False,
"use_fmtlib": False,
"cxx_modules": "auto",
"std_format": "auto",
"string_view_ret": "auto",
"no_crtp": "auto",
}
tool_requires = "cmake/[>=3.28.1]"
tool_requires = "cmake/[>=3.29]"
exports = "LICENSE.md"
exports_sources = (
"docs/*",
Expand All @@ -75,27 +86,106 @@ class MPUnitsConan(ConanFile):
no_copy_source = True

@property
def _minimum_compilers_version(self):
def _feature_compatibility(self):
return {
"gcc": "12",
"clang": "16",
"apple-clang": "15",
# , "msvc": "192"
"minimum_support": {
"std": "20",
"compiler": {
"gcc": "12",
"clang": "16",
"apple-clang": "15",
"msvc": "",
},
},
"std_format": {
"std": "20",
"compiler": {
"gcc": "13",
"clang": "17",
"apple-clang": "",
"msvc": "",
},
},
"cxx_modules": {
"std": "20",
"compiler": {"gcc": "14", "clang": "17", "apple-clang": "", "msvc": ""},
},
"static_constexpr_vars_in_constexpr_func": {
"std": "23",
"compiler": {"gcc": "13", "clang": "17", "apple-clang": "", "msvc": ""},
},
"explicit_this": {
"std": "23",
"compiler": {
"gcc": "14",
"clang": "18",
"apple-clang": "",
"msvc": "",
},
},
}

@property
def _std_format_minimum_compilers_version(self):
def _option_feature_map(self):
return {
"gcc": "13",
"clang": "17",
# , "apple-clang": "15"
# , "msvc": "192"
"std_format": "std_format",
"cxx_modules": "cxx_modules",
"string_view_ret": "static_constexpr_vars_in_constexpr_func",
"no_crtp": "explicit_this",
}

def _check_feature_supported(self, name, feature_name=name):
compiler = self.settings.compiler
cppstd = compiler.get_safe("cppstd", default_cppstd(self))
feature = self._feature_compatibility[feature_name]

# check C++ version
if not valid_min_cppstd(self, feature["std"]):
raise ConanInvalidConfiguration(
f"'{name}' requires at least cppstd={feature['std']} ({cppstd} in use)",
)

# check compiler version
min_version = feature["compiler"].get(str(compiler))
if min_version is None:
# not tested compiler being used - use at your own risk
return
if min_version == "":
raise ConanInvalidConfiguration(
f"'{name}' is not yet supported by any known {compiler} compiler"
)
if loose_lt_semver(str(compiler.version), min_version):
raise ConanInvalidConfiguration(
f"'{name}' requires at least {compiler}-{min_version} ({compiler}-{compiler.version} in use)"
)

def _is_feature_enabled(self, name):
compiler = self.settings.compiler
opt = self.options.get_safe(name)
feature_name = self._option_feature_map[name]
feature = self._feature_compatibility[feature_name]
min_version = feature["compiler"].get(str(compiler))
return bool(
opt is True
or (
opt == "auto"
and min_version
and not loose_lt_semver(str(compiler.version), min_version)
)
)

@property
def _build_all(self):
return bool(self.conf.get("user.mp-units.build:all", default=False))

@property
def _build_cxx_modules(self):
return self._is_feature_enabled("cxx_modules")

@property
def _use_fmtlib(self):
return not self._is_feature_enabled("std_format")

@property
def _skip_la(self):
return bool(self.conf.get("user.mp-units.build:skip_la", default=False))
Expand All @@ -109,7 +199,7 @@ def set_version(self):

def requirements(self):
self.requires("gsl-lite/0.41.0")
if self.options.use_fmtlib:
if self._use_fmtlib:
self.requires("fmt/10.2.1")

def build_requirements(self):
Expand All @@ -119,27 +209,10 @@ def build_requirements(self):
self.test_requires("wg21-linear_algebra/0.7.3")

def validate(self):
check_min_cppstd(self, "20")

def loose_lt_semver(v1, v2):
lv1 = [int(v) for v in v1.split(".")]
lv2 = [int(v) for v in v2.split(".")]
min_length = min(len(lv1), len(lv2))
return lv1[:min_length] < lv2[:min_length]

compiler = self.settings.compiler
min_version = self._minimum_compilers_version.get(str(compiler))
if min_version and loose_lt_semver(str(compiler.version), min_version):
raise ConanInvalidConfiguration(
f"{self.ref} requires at least {compiler} {min_version} ({compiler.version} in use)"
)
if not self.options.use_fmtlib:
min_version = self._std_format_minimum_compilers_version.get(str(compiler))
if min_version and loose_lt_semver(str(compiler.version), min_version):
raise ConanInvalidConfiguration(
f"`std::format` requires at least {compiler} {min_version} ({compiler.version} in use). "
"Use `-o use_fmtlib=True` instead."
)
self._check_feature_supported("mp-units", "minimum_support")
for key, value in self._option_feature_map.items():
if self.options.get_safe(key) is True:
self._check_feature_supported(key, value)

def layout(self):
cmake_layout(self)
Expand All @@ -148,11 +221,19 @@ def generate(self):
tc = CMakeToolchain(self)
if self._build_all:
tc.cache_variables["CMAKE_VERIFY_INTERFACE_HEADER_SETS"] = True
if self.options.cxx_modules:
tc.cache_variables["MP_UNITS_DEV_BUILD_LA"] = not self._skip_la
if self._build_cxx_modules:
tc.cache_variables["CMAKE_CXX_SCAN_FOR_MODULES"] = True
tc.cache_variables["MP_UNITS_BUILD_CXX_MODULES"] = True
tc.cache_variables["MP_UNITS_BUILD_LA"] = self._build_all and not self._skip_la
tc.cache_variables["MP_UNITS_USE_FMTLIB"] = bool(self.options.use_fmtlib)
tc.cache_variables["MP_UNITS_BUILD_CXX_MODULES"] = str(
self.options.cxx_modules
).upper()
tc.cache_variables["MP_UNITS_API_STD_FORMAT"] = str(
self.options.std_format
).upper()
tc.cache_variables["MP_UNITS_API_STRING_VIEW_RET"] = str(
self.options.string_view_ret
).upper()
tc.cache_variables["MP_UNITS_API_NO_CRTP"] = str(self.options.no_crtp).upper()
tc.generate()
deps = CMakeDeps(self)
deps.generate()
Expand Down Expand Up @@ -192,7 +273,7 @@ def package_info(self):
self.cpp_info.builddirs = ["."]
else:
self.cpp_info.components["core"].requires = ["gsl-lite::gsl-lite"]
if self.options.use_fmtlib:
if self._use_fmtlib:
self.cpp_info.components["core"].requires.append("fmt::fmt")
if compiler == "msvc":
self.cpp_info.components["core"].cxxflags = ["/utf-8"]
Expand Down
Loading

0 comments on commit 6cea16b

Please sign in to comment.