From 59bb123adff7da5a2de2c6ec0dac809a148ca8b6 Mon Sep 17 00:00:00 2001 From: Ian Geiser Date: Sun, 8 May 2022 18:31:57 +0000 Subject: [PATCH] initial add vcpkg support --- README.md | 4 +-- cookiecutter.json | 2 +- hooks/post_gen_project.py | 5 ++-- tests/test_bake_project.py | 12 ++++----- tests/test_deploy_bake.py | 2 +- .../.github/workflows/ci.yml | 27 ++++++++++--------- .../.github/workflows/sonarcloud.yml | 11 +++++--- {{cookiecutter.project_slug}}/.gitlab-ci.yml | 10 ++++--- {{cookiecutter.project_slug}}/CMakeLists.txt | 19 ++++++++++--- {{cookiecutter.project_slug}}/COPYING.md | 2 +- .../FILESTRUCTURE.md | 7 ++--- {{cookiecutter.project_slug}}/README.md | 6 ++++- {{cookiecutter.project_slug}}/TODO.md | 5 +++- {{cookiecutter.project_slug}}/pyproject.toml | 2 +- {{cookiecutter.project_slug}}/setup.py | 4 +-- {{cookiecutter.project_slug}}/vcpkg.json | 8 ++++++ 16 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/vcpkg.json diff --git a/README.md b/README.md index 630cb40..6f87f29 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,7 @@ This cookiecutter accepts the following configuration options: from the specified remote URL and the given project name. * `full_name`: Author name, defaults to `Your Name` * `license` adds a license file to the repository. It can be chosen from [MIT](https://opensource.org/licenses/MIT) (default), [BSD-2](https://opensource.org/licenses/BSD-2-Clause), [GPL-3.0](https://opensource.org/licenses/GPL-3.0), [LGPL-3.0](https://opensource.org/licenses/LGPL-3.0) or it can be omitted. -* `use_submodules`: Whether `git submodule` should be used to add version-pinned external - dependencies (like e.g. the testing framework `Catch2`). If you do not know what git submodules - are, you should select `No`. +* `externals`: How to add external resources to the project. `submodule` will use `git submodule` should be used to add version-pinned external dependencies (like e.g. the testing framework `Catch2`). `vcpkg` will use the [vcpkg](https://vcpkg.io), and if you want to use the local hosts you should select `none`. * `header_only`: Whether the C++ project is header-only. If `No` is selected, a library will be added to the project. In both cases, a target is exported that dependent projects can link against. diff --git a/cookiecutter.json b/cookiecutter.json index 0f72fa6..c5d9c87 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -4,7 +4,7 @@ "project_slug": "{%- if cookiecutter.remote_url == 'None' -%}{{ cookiecutter.project_name|replace('+', 'p')|slugify }}{% else %}{{ cookiecutter.remote_url.split('/')[-1]|replace('.git', '')}}{%- endif -%}", "full_name": "Your Name", "license": ["MIT", "BSD-2", "GPL-3.0", "LGPL-3.0", "None"], - "use_submodules": ["Yes", "No"], + "externals": ["vcpkg", "submodules", "none"], "header_only": ["Yes", "No"], "github_actions_ci": ["Yes", "No"], "gitlab_ci": ["Yes", "No"], diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 6c290e8..38a304b 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -56,7 +56,8 @@ def conditional_remove(condition, path): conditional_remove(True, "ext/.keep") -conditional_remove("{{ cookiecutter.use_submodules }}" == "No", "ext") +conditional_remove("{{ cookiecutter.externals }}" != "submodules", "ext") +conditional_remove("{{ cookiecutter.externals }}" != "vcpkg", "vcpkg.json") conditional_remove("{{ cookiecutter.license }}" == "None", "LICENSE.md") conditional_remove("{{ cookiecutter.header_only }}" == "Yes", "src") conditional_remove("{{ cookiecutter.gitlab_ci }}" == "No", ".gitlab-ci.yml") @@ -83,7 +84,7 @@ def conditional_remove(condition, path): {% if cookiecutter.remote_url != 'None' %} repo.add_remote("origin", "{{ cookiecutter.remote_url }}") {% endif %} -{% if cookiecutter.use_submodules == "Yes" %} +{% if cookiecutter.externals == "submodules" %} repo.add_submodule("https://github.com/catchorg/Catch2.git", "ext/Catch2", tag="v{{ cookiecutter._catch_version }}") if "{{ cookiecutter.python_bindings }}" == "Yes": repo.add_submodule("https://github.com/pybind/pybind11.git", "ext/pybind11", tag="v{{ cookiecutter._pybind_version }}") diff --git a/tests/test_bake_project.py b/tests/test_bake_project.py index fdabadb..5a876d2 100644 --- a/tests/test_bake_project.py +++ b/tests/test_bake_project.py @@ -44,13 +44,13 @@ def build_cmake(target=None, ctest=False, install=False, **cmake_args): @pytest.mark.local -@pytest.mark.parametrize("submodules", ("Yes", "No")) +@pytest.mark.parametrize("externals", ("submodules", "vcpkg", "none")) @pytest.mark.parametrize("header_only", ("Yes", "No")) -def test_ctest_run(cookies, submodules, header_only): +def test_ctest_run(cookies, externals, header_only): bake = cookies.bake( extra_context={ 'project_slug': 'test_project', - 'use_submodules': submodules, + 'externals': externals, 'header_only': header_only, 'sonarcloud': 'No', } @@ -177,13 +177,13 @@ def test_gitlabci(cookies): @pytest.mark.local -@pytest.mark.parametrize("submodules", ("Yes", "No")) -def test_python(cookies, virtualenv, submodules): +@pytest.mark.parametrize("externals", ("submodules", "vcpkg", "none")) +def test_python(cookies, virtualenv, externals): bake = cookies.bake( extra_context={ 'project_slug': 'my-project', 'python_bindings': 'Yes', - 'submodules': submodules, + 'externals': externals, 'sonarcloud': 'No', } ) diff --git a/tests/test_deploy_bake.py b/tests/test_deploy_bake.py index 1e4b1cd..73674f3 100644 --- a/tests/test_deploy_bake.py +++ b/tests/test_deploy_bake.py @@ -22,7 +22,7 @@ def test_push_remote(cookies): 'readthedocs': 'Yes', 'python_bindings': 'Yes', 'pypi_release': 'Yes', - 'use_submodules': 'No', + 'externals': 'none', 'codecovio': 'Yes', 'sonarcloud': 'Yes', } diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index a781e6d..541e68c 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -12,7 +12,7 @@ on: # as well as upon manual triggers through the 'Actions' tab of the Github UI workflow_dispatch: -{%- if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals != "submodules" %} env: CATCH2_VERSION: {{ cookiecutter._catch_version }} {%- if cookiecutter.python_bindings == "Yes" %} @@ -30,12 +30,15 @@ jobs: steps: - uses: actions/checkout@v2 -{% if cookiecutter.use_submodules == "Yes" %} with: submodules: 'recursive' -{%- endif %} -{% if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "vcpkg" %} + - name: Install vcpkg dependencies..." + run: | + vcpkg install +{% else %} +{% if cookiecutter.externals == "none" %} - name: Install Catch2 (Linux + MacOS) if: runner.os != 'Windows' run: | @@ -77,7 +80,7 @@ jobs: cmake --build . --target install {%- endif %} {%- endif %} - +{%- endif %} - name: make build directory run: cmake -E make_directory ${{ "{{runner.workspace}}" }}/build @@ -105,10 +108,8 @@ jobs: steps: - uses: actions/checkout@v2 -{% if cookiecutter.use_submodules == "Yes" %} with: submodules: 'recursive' -{%- endif %} - name: Set up Python uses: actions/setup-python@v2 @@ -130,17 +131,19 @@ jobs: steps: - uses: actions/checkout@v2 -{% if cookiecutter.use_submodules == "Yes" %} with: submodules: 'recursive' -{%- endif %} - name: Install LCov run: | sudo apt-get install -y lcov - -{% if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "vcpkg" %} + - name: Install vcpkg dependencies..." + run: | + vcpkg install +{% else %} +{% if cookiecutter.externals == "none" %} - name: Install Catch2 (Linux + MacOS) if: runner.os != 'Windows' run: | @@ -182,7 +185,7 @@ jobs: cmake --build . --target install {%- endif %} {%- endif %} - +{%- endif %} - name: make build directory run: cmake -E make_directory ${{ "{{runner.workspace}}" }}/build diff --git a/{{cookiecutter.project_slug}}/.github/workflows/sonarcloud.yml b/{{cookiecutter.project_slug}}/.github/workflows/sonarcloud.yml index 977e1f0..ba4d179 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/sonarcloud.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/sonarcloud.yml @@ -11,7 +11,7 @@ on: - reopened env: -{%- if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "none" %} CATCH2_VERSION: {{ cookiecutter._catch_version }} {%- if cookiecutter.python_bindings == "Yes" %} PYBIND11_VERSION: {{ cookiecutter._pybind_version }} @@ -28,8 +28,12 @@ jobs: with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis submodules: 'recursive' - -{% if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "vcpkg" %} + - name: Install vcpkg dependencies..." + run: | + vcpkg install +{% else %} +{% if cookiecutter.externals == "none" %} - name: Install Catch2 run: | git clone -b v$CATCH2_VERSION https://github.com/catchorg/Catch2.git @@ -48,6 +52,7 @@ jobs: cmake -DBUILD_TESTING=OFF .. sudo cmake --build . --target install {%- endif %} +{%- endif %} {%- endif %} - name: Install the SonarCloud Client + build wrapper run: | diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index 3dde5d8..5c9381b 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -1,7 +1,6 @@ variables: -{%- if cookiecutter.use_submodules == "Yes" %} GIT_SUBMODULE_STRATEGY: recursive -{%- else %} +{%- if cookiecutter.externals == "none" %} CATCH2_VERSION: {{ cookiecutter._catch_version }} {%- if cookiecutter.python_bindings == "Yes" %} PYBIND11_VERSION: {{ cookiecutter._pybind_version }} @@ -11,7 +10,11 @@ variables: .template: &template before_script: - echo "Installing potential dependencies..." -{% if cookiecutter.python_bindings == "Yes" and cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "vcpkg" %} + - vcpkg install +{%- endif %} +{% if cookiecutter.externals == "submodules" %} +{% if cookiecutter.python_bindings == "Yes" %} - git clone -b v$PYBIND11_VERSION https://github.com/pybind/pybind11.git - cd pybind11 - mkdir build @@ -20,7 +23,6 @@ variables: - sudo make install - cd ../.. {%- endif %} -{% if cookiecutter.use_submodules == "No" %} - git clone -b v$CATCH2_VERSION https://github.com/catchorg/Catch2.git - cd Catch2 - mkdir build diff --git a/{{cookiecutter.project_slug}}/CMakeLists.txt b/{{cookiecutter.project_slug}}/CMakeLists.txt index 2efc226..b06b014 100644 --- a/{{cookiecutter.project_slug}}/CMakeLists.txt +++ b/{{cookiecutter.project_slug}}/CMakeLists.txt @@ -1,8 +1,19 @@ cmake_minimum_required(VERSION 3.9) +{%- if cookiecutter.externals == "vcpkg" %} +# Bootstrap vcpkg +find_path(VCPKG_ROOT vcpkg + NAMES vcpkg vcpkg.exe + PATHS ENV VCPKG_ROOT ENV PATH + DOC "Path to vcpkg.exe" + REQUIRED +) +set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") +{%- endif %} # Set a name and a version number for your project: project({{ cookiecutter.project_slug }} VERSION 0.0.1 LANGUAGES CXX) + # Initialize some default paths include(GNUInstallDirs) @@ -41,11 +52,11 @@ add_subdirectory(app) # compile the tests include(CTest) if(BUILD_TESTING) - {%- if cookiecutter.use_submodules == "Yes" %} + {%- if cookiecutter.externals == "submodules" %} add_subdirectory(ext/Catch2) include(./ext/Catch2/contrib/Catch.cmake) {%- else %} - find_package(Catch2 REQUIRED) + find_package(Catch2 CONFIG REQUIRED) include(Catch) {%- endif %} add_subdirectory(tests) @@ -60,7 +71,7 @@ endif() {%- if cookiecutter.python_bindings == "Yes" %} if(BUILD_PYTHON) # Add Python bindings - {%- if cookiecutter.use_submodules == "Yes" %} + {%- if cookiecutter.externals == "submodules" %} add_subdirectory(ext/pybind11) {% else %} find_package(pybind11) @@ -68,7 +79,7 @@ if(BUILD_PYTHON) # Compile the Pybind11 module {%- set modname = cookiecutter.project_slug.replace("-", "") %} pybind11_add_module(_{{ modname }} python/{{ modname }}/_{{ cookiecutter.project_slug }}.cpp) - target_link_libraries(_{{ modname }} PUBLIC {{ cookiecutter.project_slug }}) + target_link_libraries(_{{ modname }} PUBLIC {{ cookiecutter.project_slug }} pybind11::lto pybind11::embed pybind11::module) # Install the Python module shared library install(TARGETS _{{ modname }} DESTINATION .) diff --git a/{{cookiecutter.project_slug}}/COPYING.md b/{{cookiecutter.project_slug}}/COPYING.md index 922fa3b..7a7ec5d 100644 --- a/{{cookiecutter.project_slug}}/COPYING.md +++ b/{{cookiecutter.project_slug}}/COPYING.md @@ -3,4 +3,4 @@ This is the list of copyright holders of {{ cookiecutter.project_name }}. For information on the license, see LICENSE.md. {%- endif %} -* {{ cookiecutter.full_name }}, 2020 +* {{ cookiecutter.full_name }}, 2022 diff --git a/{{cookiecutter.project_slug}}/FILESTRUCTURE.md b/{{cookiecutter.project_slug}}/FILESTRUCTURE.md index 133f956..b0364c1 100644 --- a/{{cookiecutter.project_slug}}/FILESTRUCTURE.md +++ b/{{cookiecutter.project_slug}}/FILESTRUCTURE.md @@ -28,9 +28,12 @@ generated for you: the `CMakeLists.txt` file from the directory `` is immediately executed. A comprehensive reference of CMake's capabilities can be found in the [official CMake docs](https://cmake.org/documentation/). A well-written, opinionated book for beginners and experts is [Modern CMake](https://cliutils.gitlab.io/modern-cmake/). -{%- if cookiecutter.use_submodules == "Yes" %} +{%- if cookiecutter.externals == "submodules" %} * The `ext` directory contains any submodules that were added by the cookiecutter. {%- endif %} +{%- if cookiecutter.externals == "vcpkg" %} +* The `vcpkg.json` file defines dependencies provided by [vcpkg manifest mode](https://vcpkg.io/en/docs/users/manifests.html). +{%- endif %} * Documentation configuration files {%- if cookiecutter.doxygen == "Yes" or cookiecutter.readthedocs == "Yes" %} * The Doxygen documentation is configured directly from `doc/CMakeLists.txt`. @@ -94,9 +97,7 @@ generated for you: repository if you do not need it. * Other files * `.gitignore` contains a default selection of files to omit from version control. -{%- if cookiecutter.use_submodules == "Yes" %} * `.gitmodules` tracks the state of added submodules -{%- endif %} {%- if cookiecutter.python_bindings == "Yes" %} * `setup.py` describes the Python package build process. This file enables you to also install your software using e.g. `pip`. diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index f7bb8ec..a992de3 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -54,9 +54,13 @@ Building {{ cookiecutter.project_name }} requires the following software install {%- if cookiecutter.doxygen == "Yes" or cookiecutter.readthedocs == "Yes" %} * Doxygen (optional, documentation building is skipped if missing) {%- endif %} -{%- if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "vcpkg" %} +* The package manager [vcpkg](https://vcpkg.io) +{% else %} +{%- if cookiecutter.externals != "submodules" %} * The testing framework [Catch2](https://github.com/catchorg/Catch2) for building the test suite {%- endif %} +{%- endif %} {%- if cookiecutter.python_bindings == "Yes" -%} * Python `>= 3.6` for building Python bindings {%- endif %} diff --git a/{{cookiecutter.project_slug}}/TODO.md b/{{cookiecutter.project_slug}}/TODO.md index c514a98..ec4208f 100644 --- a/{{cookiecutter.project_slug}}/TODO.md +++ b/{{cookiecutter.project_slug}}/TODO.md @@ -11,12 +11,15 @@ The following tasks need to be done to get a fully working project: * Make sure that the following software is installed on your computer: * A C++-{{ cookiecutter.cxx_minimum_standard}}-compliant C++ compiler * CMake `>= 3.9` -{%- if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals == "submodules" %} * The testing framework [Catch2](https://github.com/catchorg/Catch2) {%- if cookiecutter.python_bindings == "Yes" -%} * The [PyBind11](https://github.com/pybind/pybind11) library {%- endif %} {%- endif %} +{%- if cookiecutter.externals == "vcpkg" %} + * Make sure [vcpkg](https://vcpkg.io) is installed and `VCPKG_ROOT` is defined. +{%- endif %} {%- if cookiecutter.gitlab_ci == "Yes" %} * Make sure that CI/CD pipelines are enabled in your Gitlab project settings and that there is a suitable Runner available. If you are using the cloud-hosted gitlab.com, diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 37b7109..5f1435a 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=42", "wheel", "scikit-build", "cmake>=3.9"{% if cookiecutter.use_submodules == "No" %}, "pybind11[global]=={{ cookiecutter._pybind_version }}"{% endif %}] +requires = ["setuptools>=42", "wheel", "scikit-build", "cmake>=3.9"{% if cookiecutter.externals != "submodules" %}, "pybind11[global]=={{ cookiecutter._pybind_version }}"{% endif %}] build-backend = "setuptools.build_meta" [tool.pytest.ini_options] diff --git a/{{cookiecutter.project_slug}}/setup.py b/{{cookiecutter.project_slug}}/setup.py index bb601bd..13a9137 100644 --- a/{{cookiecutter.project_slug}}/setup.py +++ b/{{cookiecutter.project_slug}}/setup.py @@ -1,6 +1,6 @@ {%- set modname = cookiecutter.project_slug.replace('-', '') -%} from skbuild import setup -{%- if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals != "submodules" %} import os import pybind11 {%- endif %} @@ -31,7 +31,7 @@ cmake_args=[ "-DBUILD_TESTING=OFF", "-DBUILD_DOCS=OFF", -{%- if cookiecutter.use_submodules == "No" %} +{%- if cookiecutter.externals != "submodules" %} f"-DCMAKE_PREFIX_PATH={os.path.dirname(pybind11.__file__)}", {%- endif %} ], diff --git a/{{cookiecutter.project_slug}}/vcpkg.json b/{{cookiecutter.project_slug}}/vcpkg.json new file mode 100644 index 0000000..437cdb2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/vcpkg.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json", + "name": "{{ cookiecutter.project_slug }}", + "version": "0.0.1", + "dependencies": [ + "catch2"{%- if cookiecutter.python_bindings == "Yes" %},"pybind11"{%- endif %} + ] + } \ No newline at end of file