{"id":21726857,"url":"https://github.com/palacaze/gateau","last_synced_at":"2025-04-12T23:30:58.874Z","repository":{"id":41178089,"uuid":"297476512","full_name":"palacaze/gateau","owner":"palacaze","description":"Make software building with CMake a piece of cake","archived":false,"fork":false,"pushed_at":"2025-01-23T17:57:52.000Z","size":276,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-26T17:41:47.549Z","etag":null,"topics":["cmake","cmake-modules","cpp"],"latest_commit_sha":null,"homepage":"","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/palacaze.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-21T22:35:45.000Z","updated_at":"2025-02-10T15:25:44.000Z","dependencies_parsed_at":"2024-06-10T09:32:17.593Z","dependency_job_id":"2bdc8623-8c8a-45e5-93be-55e16602b4c4","html_url":"https://github.com/palacaze/gateau","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palacaze%2Fgateau","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palacaze%2Fgateau/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palacaze%2Fgateau/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palacaze%2Fgateau/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/palacaze","download_url":"https://codeload.github.com/palacaze/gateau/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647258,"owners_count":21139081,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","cmake-modules","cpp"],"created_at":"2024-11-26T03:40:23.775Z","updated_at":"2025-04-12T23:30:58.850Z","avatar_url":"https://github.com/palacaze.png","language":"CMake","readme":"# Gateau CMake Modules\n\n*Gateau* consists in a set of CMake modules that make working with CMake both\neasier and safer.\n\nIt has been designed as a pragmatic tool to quickly create a working CMake\nconfiguration for C++ projects. As such, it is quite opinionated and equipped to\nhandle the situations I commonly encounter. However, it may not be able to cope\nwith random project layouts and unusual or complex needs.\nMy primary use case for Gateau is avoiding repeating myself again and again by\ncopy pasting the same code from project to project, and keeping clear of all the\ntedious boilerplate that distracts me from the real task at hand.\n\nThis tool is currently being used to build C++ software, mostly on GNU/Linux,\nsometimes on MS Windows, using the GCC, Clang and MinGW compilers. Help will be\nneeded to improve compatibility with other systems and compiler combinations.\n\n## Features\n\nGateau aims to simplify the definition of the CMake configuration for your\nproject. To paraphrase a famous book title, It does so by automating the boring\nstuff, and choosing sane defaults so you don't need to.\n\nIt contains a few functions, macros and configuration variables that make it\nvery simple to create an installable project with external dependencies, a few\ntargets, unit tests and generated documentation.\n\nIn particular it is capable of:\n\n- Setting up useful options to make C++ development convenient:\n  - Sane compiler options,\n  - Sanitizers integration,\n  - LTO, CCache use...\n- Looking for dependencies, downloading and compiling them for you if missing,\n- Declaring new targets that will be configured in a sensible way for you to\n  make it both installable and importable by other projects. An export header\n  and version header get generated for every target.\n- Making targets trivially installable, with automatic installation of binaries,\n  headers as well as generation of CMake config, version and target modules so\n  that your project can be found and used by other projects.\n- Declaring tests in a simple way,\n- Automatically generating Doxygen documentation,\n- ...\n\nAgain, it is a simple tool, not a full-fledged package manager. It does not\nparticularly excel at dependency handling and will not be able to cope with\ncomplex dependency chains.\n\n## Motivational example\n\nThe following file listings illustrate the main features of Gateau. For a more\ncomplete overview, the examples directory showcases both the complete installable\nproject presented below as well as a second project using the first one as an\nexternal dependency.\n\n### Main CMakeLists.txt\n\n```cmake\ncmake_minimum_required(VERSION 3.15)\n\n# Project definition\nproject(eclair\n    VERSION 0.1\n    DESCRIPTION \"A yummy project\"\n    HOMEPAGE_URL \"https://www.yummy-eclair.pro\"\n    LANGUAGES CXX\n)\n\n# Include Gateau by fetching it. One may also use it as a submodule\ninclude(FetchContent)\nFetchContent_Declare(gateau GIT_REPOSITORY https://github.com/palacaze/gateau.git)\nFetchContent_MakeAvailable(gateau)\ninclude(${gateau_SOURCE_DIR}/Gateau.cmake)\n\n# Configure gateau for this project\ngateau_configure(\n    EXTERNAL_ROOT \"${PROJECT_BINARY_DIR}/3rdparty\"\n    OUTPUT_DIRECTORY \"${PROJECT_SOURCE_DIR}/bin\"\n    GENERATED_HEADER_CASE HYPHEN\n    GENERATED_HEADER_EXT hpp\n)\n\n# Looking for fmtlib\ngateau_find_package(fmt GIT https://github.com/fmtlib/fmt)\n\n# The main sources\nadd_subdirectory(src)\n\n# Tests\nif (ECLAIR_BUILD_TESTS)\n    add_subdirectory(test)\nendif()\n\n# Documentation\nif (ECLAIR_BUILD_DOC)\n    gateau_build_documentation(\n        EXCLUDED_SYMBOLS\n            detail  # exclude \"detail\" namespace\n            _*      # and symbols starting with a \"_\"\n    )\nendif()\n\n# Other files we would like to see in the IDE\nfile(GLOB_RECURSE _doc_files \"doc/*.md\")\ngateau_other_files(Doc\n    README.md\n    ${_doc_files}\n)\n\n# Installation\ngateau_install_project()\n```\n\n### src/eclair/CMakeLists.txt\n\n```cmake\n# Create the \"lib\" library\ngateau_add_library(lib\n    SOURCES\n        eclair.cpp\n    HEADERS\n        eclair.hpp\n    LINK_LIBRARIES\n        PUBLIC\n            fmt\n)\n```\n\n### src/bakery/CMakeLists.txt\n\n```cmake\n# Create an executable that uses the \"lib\" library\ngateau_add_executable(bakery\n    SOURCES bakery.cpp\n    LINK_LIBRARIES eclair::lib\n)\n```\n\n### test/CMakeLists.txt\n\n```cmake\n# I use Doctest for my unit tests\ngateau_setup_testing(tests DOCTEST)\n\ngateau_add_test(test-lib\n    SOURCES\n        test-lib.cpp\n        test-main.cpp\n    LINK_LIBRARIES\n        eclair::lib\n)\n```\n\n## Status\n\nWorks for me. I use *Gateau* for several projects and it works surprisingly well for\nwhat I want. It has not been tested at all on Windows yet, but it will someday.\n\nMy TODO list includes a lot of potentially useful stuff, but I do not require these\nfeatures right now so I make no promise.\n\n- Install headers only libs from an archive file or path,\n- Allow a gateau_fetch_package() that uses FetchContent instead of ExternalProject,\n- Support Qt translations,\n- Support Gitlab, Gihub automation,\n- Automated project deployment and packaging, for instance with CPack,\n- Conan integration,\n- Add an option for configurable compiler flags.\n- Allow Package modules versioning,\n- ...\n\n## Requirements\n\n### CMake\n\nOnly CMake is needed. Version 3.15 or later is mandatory, as Gateau modules\nrely on recent CMake constructs to achieve their goals.\n\n### Project organization\n\nThe project layout on the file system is not imposed but it is recommended to\norganize public headers in the same way you want them installed. That way it will\nbe possible to automate installation.\n\nA possible layout is the following:\n\n```\nProject\n├── CMakeLists.txt\n├── data/\n│  └── Misc.svg\n├── doc/\n├── example/\n│  ├── CMakeLists.txt\n│  ├── Example1.cpp\n│  └── Example2.cpp\n├── README.md\n├── src/\n│  └── Project/\n│     └── Target/\n│        ├── CMakeLists.txt\n│        ├── File.h\n│        ├── File.cpp\n│        └── PublicHeader1.h\n│        └── PublicHeader2.h\n└── test/\n   ├── CMakeLists.txt\n   ├── Test1.cpp\n   └── Test2.cpp\n```\n\nThis makes it possible to `#include \u003cProject/Target/PublicHeader1.h\u003e` from any\nother public header. Having `test` and `example` directories (notice the singular)\nallow defining idiomatic `tests` and `examples` CMake targets.\n\n\nAnother popular layout is to put the public headers in the `include` directory:\n\n```\nProject\n├── CMakeLists.txt\n├── include/\n│  └── Project/\n│     └── Target/\n│        ├── CMakeLists.txt\n│        └── PublicHeader1.h\n│        └── PublicHeader2.h\n├── README.md\n├── src/\n   └── Target/\n      ├── CMakeLists.txt\n      ├── File.h\n      ├── File.cpp\n```\n\n*Gateau* can be customized to look for public headers from other base directories,\nchances are that you current project layout can be handled with no change.\n\n## User Manual\n\nThe Gateau.cmake module is the main entry point of Gateau's CMake modules\ndistribution. It should be included right after the call project() command, near\nthe top of a project's top level CMakeLists.txt.\n\nAll the other modules are included from this one, so no other inclusion is\nnecessary.\n\nCMake version 3.15 or later is required.\n\n### Using Gateau in your project\n\nOne can include *Gateau* as a git submodule, integrate it in its own project or simply\nuse FetchContent to incorporate it at configuration time.\n\nThe following snippet near the top of the root CMakeLists.txt of a project should suffice:\n\n```cmake\n# Fetch Gateau\ninclude(FetchContent)\nFetchContent_Declare(gateau GIT_REPOSITORY https://github.com/palacaze/gateau.git)\nFetchContent_MakeAvailable(gateau)\ninclude(${gateau_SOURCE_DIR}/Gateau.cmake)\n```\n\n### Configuration and user visible options\n\nAfter inclusion of Gateau's main module, a number of cache variables get defined.\nThey can be categorized into 4 different groups:\n\n- Internal variables used by *Gateau* itself,\n- Variables that describe the system,\n- Hidden variables used to setup low-level aspects of a *Gateau*-based project,\n- User-visible variables that can be used to tweak the configuration of a project.\n\nEach variable is prefixed with an identifier created from the project name. The\nidentifier is obtained by separating the words of the project name and producing\nan all-caps C identifier equivalent string of it. For instance:\n\n| Project Name | Equivalent Prefix |\n|--------------|-------------------|\n| myproj       | MYPROJ            |\n| my-proj      | MY_PROJ           |\n| Myproj       | MYPROJ            |\n| MyProj       | MY_PROJ           |\n| my_proj      | MY_PROJ           |\n\nThis prefix identifier is stored in the `${PROJECT_NAME}_IDENT` cache variable.\nThe reason for prefixing variables is to allow Gateau-based sub-projects.\n\nHere is a breakdown of the variables generated by *Gateau*, by type.\n\n#### Informative variables\n\nThose are conceptually read-only.\n\n| Variable              | Description                                    | Value     |\n|-----------------------|------------------------------------------------|-----------|\n| ${PROJECT_NAME}_IDENT | The identifier string used to prefix variables | ${ID}     |\n| ${ID}_ARCH            | The architecture pointer size                  | 32 or 64  |\n| ${ID}_X32             | Is this a 32 bits build                        | ON or OFF |\n| ${ID}_X64             | Is this a 64 bits build                        | ON or OFF |\n\n#### Low-level configuration variables\n\nThose are meant for the project developers.\n\n| Variable                    | Description                                       | Default                        |\n|-----------------------------|---------------------------------------------------|--------------------------------|\n| ${ID}_RELATIVE_HEADERS_DIRS | Dirs where headers are expected to be found       | src;include;Src;Source;Include |\n| ${ID}_GENERATED_HEADER_CASE | How to name generated headers (CAMEL/SNAKE/HYPEN) | SNAKE                          |\n| ${ID}_GENERATED_HEADER_EXT  | Extension of generated headers                    | \"hpp\"                          |\n| ${ID}_NAMESPACE             | The namespace used for alias targets and exports  | \"${PROJECT_NAME}\"              |\n| ${ID}_C_STANDARD            | The C standard to use                             | c_std_99                       |\n| ${ID}_CXX_STANDARD          | The C++ standard to use                           | cxx_std_17                     |\n| ${ID}_NAME_PREFIX           | The default prefix to use for output file names   | \"\"                             |\n| ${ID}_LIBRARY_NAME_PREFIX   | The prefix to use for library output file names   | \"\"                             |\n| ${ID}_RUNTIME_NAME_PREFIX   | The prefix to use for runtime output file names   | \"\"                             |\n\n\n`${ID}_RELATIVE_HEADERS_DIRS` can be used to teach *Gateau* about the project layout,\nand will be used to install the project's development headers correctly.\n\n`${ID}_GENERATED_HEADER_CASE` and `${ID}_GENERATED_HEADER_EXT` and describes\nhow one wishes the generated headers to be named. Right now, two header\nfiles may be generated for a given target: a version header and an export\nheader.\n\n| Case   | Result           |\n|--------|------------------|\n| CAMEL  | TargetVersion.h  |\n| SNAKE  | target_version.h |\n| HYPHEN | target-version.h |\n\n`${ID}_NAME_PREFIX`, `${ID}_LIBRARY_NAME_PREFIX` and `${ID}_RUNTIME_NAME_PREFIX`\ncan be used to add a custom prefix to the names of targets output names. For instance\na library target named `foo` with `${ID}_LIBRARY_NAME_PREFIX` set to 'bar' may be\nnamed libbarfoo.so on some platforms.\n\n\n#### Options and cache variables\n\nThe following variables can be set by the user to tweak how the project will be\nconfigured and built. They can grouped thematically.\n\n##### Options that control what gets built\n\nThe `${ID}_BUILD_XXXX` options can be used by the project developer to selectively\ndeactivate parts of the project to be built.\n\n| Option                 | Description         | Default |\n|------------------------|---------------------|---------|\n| ${ID}_BUILD_EXAMPLES   | Build code examples | ON      |\n| ${ID}_BUILD_TESTS      | Build tests         | ON      |\n| ${ID}_BUILD_DOC        | Build documentation | ON      |\n| ${ID}_BUILD_BENCHMARKS | Build benchmarks    | OFF     |\n\n##### Options that affect the compilation\n\nA number of options can be used to change the compiler flags.\n\n| Option                         | Description                                                   | Default    |\n|--------------------------------|---------------------------------------------------------------|------------|\n| ${ID}_ENABLE_AUTOSELECT_LINKER | Select the best available linker                              | ON         |\n| ${ID}_ENABLE_COMMON_WARNINGS   | Enable common compiler flags                                  | ON         |\n| ${ID}_ENABLE_LIBCXX            | Use libc++ instead of gcc standard library                    | OFF        |\n| ${ID}_ENABLE_LTO               | Enable link time optimization (release only)                  | OFF        |\n| ${ID}_ENABLE_MANY_WARNINGS     | Enable more compiler warnings                                 | OFF        |\n| ${ID}_ENABLE_PROFILING         | Add compile flags to help with profiling                      | OFF        |\n| ${ID}_ENABLE_WERROR            | Enable werror for a few important compiler flags              | ON         |\n| ${ID}_KEEP_TEMPS               | Keep temporary compiler-generated files for debugging purpose | OFF        |\n| ${ID}_SANITIZE_ADDRESS         | Compile with address sanitizer support                        | OFF        |\n| ${ID}_SANITIZE_THREADS         | Compile with thread sanitizer support                         | OFF        |\n| ${ID}_SANITIZE_UNDEFINED       | Compile with undefined sanitizer support                      | OFF        |\n| ${ID}_SPLIT_DEBUG_INFO         | Split debug info (may not compatible with sanitizers)         | ON         |\n| ${ID}_USE_CCACHE               | Use Ccache to speed-up compilation                            | OFF        |\n\n##### Options that control where build artifacts get stored\n\n`BD = PROJECT_BINARY_DIR`\n\n| Option                   | Description                               | Default   |\n|--------------------------|-------------------------------------------|-----------|\n| ${ID}_OUTPUT_DIRECTORY   | Where to place compiled targets           | \"\"        |\n| ${ID}_DOCUMENTATION_ROOT | Documentation installation root directory | ${BD}/doc |\n\n##### Options that control how external dependencies are build\n\nGateau has limited ability to install missing external dependencies. This feature\ncan be disabled with the `${ID}_NO_INSTALL_DEPS` option. At the other side of the\nspectrum, `${ID}_UPDATE_DEPS` can be used to instruct Gateau to update external\ndependencies. This is useful for projects that rely on multiple related third\nparty components highly coupled but managed in distinct repositories.\n\nThe other options are meant to tweak external dependencies handling.\n\n| Option                        | Description                                                   | Default                |\n|-------------------------------|---------------------------------------------------------------|------------------------|\n| ${ID}_NO_BUILD_DEPS           | Prevent Gateau from building missing external dependencies    | OFF                    |\n| ${ID}_UPDATE_DEPS             | Update the external packages when the project is reconfigured | OFF                    |\n| ${ID}_EXTERNAL_ROOT           | Root directory where external packages get handled            | ${BD}/external         |\n| ${ID}_EXTERNAL_BUILD_TYPE     | Build type used to build external packages                    | Release                |\n| ${ID}_EXTERNAL_INSTALL_PREFIX | Prefix where to install built external packages               | EXTERNAL_ROOT/prefix   |\n| ${ID}_DOWNLOAD_CACHE          | Directory that acts as a download cache for external packages | EXTERNAL_ROOT/download |\n\n### Project creation\n\nApart from including the main *Gateau* module, some of the configuration variables,\nthe one targeting the project itself, can be passed using an optional call to\n*gateau_configure*.\n\n```\ngateau_configure(\n    [NO_BUILD_DEPS] [UPDATE_DEPS]\n    [C_STANDARD \u003cc_std\u003e] [CXX_STANDARD \u003ccxx_std\u003e]\n    [GENERATED_HEADER_CASE \u003cCAMEL|SNAKE|HYPHEN\u003e]\n    [GENERATED_HEADER_EXT \u003cext\u003e]\n    [OUTPUT_DIRECTORY \u003cout_dir\u003e]\n    [DOWNLOAD_CACHE \u003cdown_dir\u003e]\n    [NAMESPACE \u003cnamespace\u003e]\n    [NAME_PREFIX \u003cprefix\u003e]\n    [LIBRARY_NAME_PREFIX \u003clibrary_prefix\u003e]\n    [RUNTIME_NAME_PREFIX \u003cruntime_prefix\u003e]\n    [EXTERNAL_BUILD_TYPE \u003cbuild_type\u003e]\n    [EXTERNAL_ROOT \u003cext_root_dir\u003e]\n    [EXTERNAL_INSTALL_PREFIX \u003cext_prefix\u003e]\n    [RELATIVE_HEADERS_DIRS [items...]])\n\n```\n\nThe options are the same as described earlier, and allow the project developer\nto tweak Gateau for the needs of the project.\n\n### Finding dependencies\n\n*Gateau* offers a wrapper over the find_packages facilities to improve and\nextend the function to include automated compilation of external dependencies\nas well as integrate those dependencies in the CMake find modules that will\nbe generated for the project.\n\nTo do so, simply replace calls to `find_package` with calls to `gateau_find_package`.\n\nThis macro supplements the `find_package` function with additional features that\nallow overriding package finding instructions, as well as instruct CMake how to\ndownload, and install the dependency itself if it was not found.\n\nTo do so, Gateau relies on the creation of special CMake modules, named after the\npackage to be found, which define variables and a couple of macros to instruct\nGateau on how the package should be found and installed. Installation itself is\ndeferred to the CMake ExternalProject module.\n\nGateau comes with a few custom package instruction modules for dependencies I use\nor have used in the past. Any project can add additional modules in its own tree\nby declaring the directory that contains them to *Gateau*.\n\n```\n# Add a directory to the list of directories to search when looking for a\n# package module file with installation instructions for external dependencies.\ngateau_add_package_module_dir(\u003cdir\u003e)\n```\n\nCreating such modules is not mandatory to benefit from the capabilities offered\nby `gateau_find_package`. One can also supply custom directives directly to the\nmacro. For this reason, `gateau_find_package` offers a number of parameters,\nmost of them mirror those from ExternalProject_add, which will mostly be passed\nas-is to the function.\n\n```\ngateau_find_package(\u003cname\u003e\n    [IN_SOURCE]\n    [NO_EXTRACT] [NO_PATCH] [NO_UPDATE]\n    [NO_CONFIGURE] [NO_BUILD] [NO_INSTALL]\n    [OPTIONAL]\n    [BUILD_ONLY_DEP]\n    [UPDATE_DEP]\n    [GIT \u003cgit_url\u003e]\n    [TAG \u003cgit_tag\u003e]\n    [URL \u003cfile_url\u003e]\n    [MD5 \u003cfile_md5\u003e]\n    [SOURCE_SUBDIR \u003csubdir\u003e]\n    [SINGLE_HEADER \u003cheader_url\u003e]\n    [CMAKE_CACHE_ARGS args...]\n    [CMAKE_ARGS args...]\n    [PATCH_COMMAND commands...]\n    [UPDATE_COMMAND commands...]\n    [CONFIGURE_COMMAND commands...]\n    [BUILD_COMMAND commands...]\n    [INSTALL_COMMAND commands...])\n```\n\nContrary to find_package, gateau_find_package defaults to `REQUIRED`. For optional\ndependencies, the `OPTIONAL` keyword must be used.\n\nThat way, by merely adding a GIT or URL directive to `gateau_find_package`, one can\ntransform a normal `find_package` directive into one that can fetch compile and install\nthe dependency for you (assuming a CMake installable dependency).\n\nHere is one such example:\n\n```cmake\ngateau_find_package(spdlog https://github.com/gabime/spdlog)\ngateau_add_executable(foo\n    SOURCES foo.cpp\n    LINK_LIBRARIES spdlog::spdlog)\n\n```\n\n#### Build-only dependencies\n\nSome dependencies may be build-only deps, for instance headers-only libraries used\nin private parts or code generation tools. The installed package does not depend on\nit and as such does not constitute a runtime dependency. Those can be marked using\nthe `BUILD_ONLY_DEP` option, and will not be added to the package config module\ninstalled with the package.\n\n#### Special case for single header libraries\n\n`gateau_find_package` possesses an option dedicated to single header libraries.\nIt allows installing such a library by supplying an URL to the header file.\n\nThe `${name}::${name}` import target gets generated automatically and can be linked to.\n\n```cmake\ngateau_find_package(date\n    SINGLE_HEADER \"https://github.com/HowardHinnant/date/raw/master/include/date/date.h\")\ngateau_add_executable(foo\n    SOURCES foo.cpp\n    LINK_LIBRARIES date::date)\n```\n\n#### Creating package modules for external dependencies\n\nA package module file named after the dependency to be installed and placed in an appropriate\ndirectory can be created to instruct Gateau how to find and install a particular package.\nThe complete file will be sourced by Gateau.\n\nThe variables accepted by gateau_find_package can be defined in this module, but must\nbe prefixed with the package name. For instance, the module for a package \"Dep\" may\ncontain the variable Dep_URL.\n\nMoreover, two macros may optionally be defined, also prefixed with the package name:\n\n- ${dep}_find(name optional_find_options...)\n- ${dep}_install(name)\n\nThe first macro gets called when the dependency is searched. A default implementation would\ndispatch all the arguments to find_package(). This is where one would handle custom search\nprocedure and define import targets if the default package distribution does not provide any,\nfor instance for old style cmake packages and non-cmake built packages.\n\nThe second is responsible for installing the dependency, and gets called if the depenency\nwas not found. Most of the time, one wants to use `gateau_install_dependency()` for that.\nThis is a wrapper over ExternalProject_add that knows how to use some variables prefixed with\nthe package name to setup the installation procedure.\n\nFor illustration purpose, here is a complete annoted module example of package module for\na dependency that is not CMake compatible:\n\n```cmake\n# This is asio.cmake, a package module that provides custom search and installation\n# procedure for the standalone asio library.\n\n# First a couple of variables that instruct gateau_install_dependency() how to fetch\n# the asio source code from its git repository.\nset(asio_GIT \"https://github.com/chriskohlhoff/asio.git\")\nset(asio_TAG \"asio-1-18-0\")\n\n# The _find macro gets called when the package is searched.\nmacro(asio_find name)\n    # Standard package finding procedure\n    include(FindPackageHandleStandardArgs)\n\n    find_path(asio_INCLUDE_DIR\n        NAMES io_service.hpp\n        PATH_SUFFIXES asio\n    )\n\n    find_package_handle_standard_args(\n        asio DEFAULT_MSG asio_INCLUDE_DIR)\n\n    mark_as_advanced(asio_INCLUDE_DIR)\n\n    # We also create an import target for nicer use\n    if(asio_FOUND AND NOT TARGET asio::asio)\n        add_library(asio::asio INTERFACE IMPORTED)\n        set_target_properties(asio::asio PROPERTIES\n            INTERFACE_INCLUDE_DIRECTORIES \"${asio_INCLUDE_DIR}\"\n        )\n        target_compile_definitions(asio::asio INTERFACE\n            BOOST_ASIO_NO_DEPRECATED\n            BOOST_ASIO_STANDALONE\n            BOOST_ASIO_HEADER_ONLY\n        )\n    endif()\nendmacro()\n\n# The _install macro is called to install the package is not found.\nmacro(asio_install name)\n    # Call to gateau_install_dependency, which installs the dep\n    # For this header only package, we specifically instruct cmake to skip unwanted steps\n    gateau_install_dependency(${name}\n        NO_PATCH\n        NO_CONFIGURE\n        NO_BUILD\n        INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory \"\u003cINSTALL_DIR\u003e/include/asio\"\n                COMMAND ${CMAKE_COMMAND} -E copy_directory \"\u003cSOURCE_DIR\u003e/asio/include/asio\" \"\u003cINSTALL_DIR\u003e/include/asio\"\n                COMMAND ${CMAKE_COMMAND} -E copy \"\u003cSOURCE_DIR\u003e/asio/include/asio.hpp\" \"\u003cINSTALL_DIR\u003e/include\"\n    )\nendmacro()\n```\n\nMost of the time, for packages already supporting CMake, the package module will\nonly contain a few variables to setup the package URL or GIT repo and custom CMAKE_ARGS.\nThe packages directory contains a few modules ready for use that can serve as example.\n\n`gateau_install_dependency()` has the following signature:\n\n```\n# Function that simplifies working with ExternalProject_Add.\n# It sets an ExternalProject up using the supplied available information and\n# creates an install and uninstall target for later use.\n#\n# The list of recognized arguments is enumerated below, and mostly matches the\n# names and meaning of the one accepted by ExternalProject_add.\n#\n# The arguments used to configure the external project are retrieved from two\n# sources: the arguments supplied to the function, as well as any variable in\n# scope that has the form ${dep}_OPTION_NAME, where OPTION_NAME is a variable\n# name from the parameters list below.\n#\n# Unrecognized arguments will be passed as-is to ExternalProject_Add.\ngateau_install_dependency(\u003cname\u003e\n    [IN_SOURCE]\n    [NO_EXTRACT] [NO_CONFIGURE] [NO_PATCH]\n    [NO_UPDATE] [NO_BUILD] [NO_INSTALL]\n    [GIT \u003cgit_repo\u003e]\n    [TAG \u003cgit_tag\u003e]\n    [URL \u003cfile_url\u003e]\n    [MD5 \u003cfile_md5\u003e]\n    [SOURCE_SUBDIR \u003csubdir\u003e]\n    [GIT_CONFIG config...]\n    [CMAKE_CACHE_ARGS args...]\n    [CMAKE_ARGS args...]\n    [PATCH_COMMAND cmds...]\n    [UPDATE_COMMAND cmds...]\n    [CONFIGURE_COMMAND cmds...]\n    [BUILD_COMMAND cmds...]\n    [INSTALL_COMMAND cmds...])\n```\n\nLook up the ExternalProject_add documentation for more information on each option.\n\n### Creating targets\n\nOne of the design goals of *Gateau* is to provide clean an consistent APIs.\nTo that hand, the number of actual functions to create and configure targets is\nreduced to the bare minimum:\n\n- `gateau_add_library()` to create a new library target\n- `gateau_add_executable()` to create a new executable target\n- `gateau_extend_target()` to modify a target\n\nMost aspects of a target can be parametrized through calls to those three functions.\nThe first two calls declare new library and executable targets respectively, whereas\nthe last one extends an already existing target.\n\nAll the parameters accepted by `gateau_extend_target()` can also be passed to the other\ntwo functions, and will be forwarded to it.\n\n#### Defining a new library target\n\n```\ngateau_add_library(\u003cname\u003e\n    [STATIC | SHARED | OBJECT | MODULE | INTERFACE]\n    [SYSTEM]\n    [NO_INSTALL] [NO_INSTALL_HEADERS]\n    [NO_EXPORT]\n    [NO_EXPORT_HEADER]\n    [NO_VERSION_HEADER]\n    [INSTALL_BINDIR \u003cdir\u003e]\n    [INSTALL_LIBDIR \u003cdir\u003e]\n    [INSTALL_INCLUDEDIR \u003cdir\u003e]\n    [other options accepted by gateau_extend_target()]...\n)\n```\n\nThe following options are accepted:\n\n- One of STATIC SHARED OBJECT MODULE INTERFACE (defaults to SHARED): library type\n- SYSTEM: set the SYSTEM keywords to include directories\n- NO_INSTALL: do not install this target\n- NO_INSTALL_HEADER: do not install the dev headers\n- NO_EXPORT: the target is not exported to the cmake package module installed\n- NO_EXPORT_HEADER: do not generate an export header\n- NO_VERSION_HEADER: do not generate a version header\n- INSTALL_BINDIR: override the binaries installation directory path\n- INSTALL_LIBDIR: override the libraries installation directory path\n- INSTALL_INCLUDEDIR: override the headers installation directory path\n- Other options.... parameters forwarded to `gateau_extend_target()`\n\nAutomated installation and generation of both an export and version header are some of\nthe benefits of creating library targets through a call to `gateau_add_library()`.\n\nThe target also gets an alias of the form ${Project}::${Target} and also makes\nuse of all the options defined at project scope.\n\nMost of the time, a single call to gateau_add_library() will suffice to\ndefine the whole target. See the documentation for `gateau_extend_target()` below\nto learn how to configure the other function parameters.\n\nAlso of note, `gateau_add_library()` should work out of the box with interface libraries.\n\n#### Defining a new executable target\n\n```\ngateau_add_executable(\u003cname\u003e\n    [NO_INSTALL]\n    [NO_EXPORT]\n    [VERSION_HEADER]\n    [INSTALL_BINDIR \u003cdir\u003e]\n    [other options accepted by gateau_extend_target()]...\n)\n```\n\nThe following options are accepted:\n\n- One of STATIC SHARED OBJECT MODULE INTERFACE (defaults to SHARED): library type\n- NO_INSTALL: do not install this target\n- NO_EXPORT: the target is not exported to the cmake package module installed\n- VERSION_HEADER: do generate a version header\n- INSTALL_BINDIR: override the binaries installation directory path\n- Other options.... parameters forwarded to `gateau_extend_target()`\n\n#### Configuring a target\n\nBoth `gateau_add_library()` and `gateau_add_executable()` forward unused arguments to\n`gateau_extend_target()`. Several calls to this function can be performed to augment\na target.\n\n```\ngateau_extend_target(\u003ctarget\u003e\n    [AUTOMOC]\n    [AUTOUIC]\n    [AUTORCC]\n    [EXCLUDE_FROM_ALL]\n    [NO_INSTALL_HEADERS]\n    [CONDITION \u003ccondition\u003e]\n    [SOURCES             [PUBLIC|PRIVATE|INTERFACE] srcs...]\n    [HEADERS             [PUBLIC|PRIVATE|INTERFACE] hdrs...]\n    [COMPILE_DEFINITIONS [PUBLIC|PRIVATE|INTERFACE] defs...]\n    [COMPILE_FEATURES    [PUBLIC|PRIVATE|INTERFACE] feats...]\n    [COMPILE_OPTIONS     [PUBLIC|PRIVATE|INTERFACE] opts...]\n    [INCLUDE_DIRECTORIES [PUBLIC|PRIVATE|INTERFACE] dirs...]\n    [LINK_DIRECTORIES    [PUBLIC|PRIVATE|INTERFACE] dirs...]\n    [LINK_OPTIONS        [PUBLIC|PRIVATE|INTERFACE] opts...]\n    [LINK_LIBRARIES      [PUBLIC|PRIVATE|INTERFACE] libs...]\n    [PROPERTIES          [PROP_NAME \u003cprop_value\u003e]...]\n)\n```\n\nThe function call wraps all the aspects of a target configuration, with options\nthat map to the various cmake functions that act on a target. Visibility can be\ntweaked per option.\nHere is a rundown:\n\n- AUTOMOC, AUTOUIC and AUTORCC activate the corresponding properties for the target\n- EXCLUDE_FROM_ALL excludes the target from the all target.\n- NO_INSTALL_HEADERS skips headers installation for a target\n- CONDITION a boolean that dictates if the call to `gateau_extend_target()` must be applied\n- SOURCES calls `target_sources()`, declares non installable sources (and also private headers)\n- HEADERS calls `target_sources()`, declares headers that must be installed with the binary target\n- COMPILE_DEFINITIONS calls `target_compile_definitions()`\n- COMPILE_FEATURES calls `target_compile_features()`\n- COMPILE_OPTIONS calls `target_compile_options()`\n- INCLUDE_DIRECTORIES `target_include_directories()`\n- LINK_DIRECTORIES calls `target_link_directories()`\n- LINK_OPTIONS calls `target_link_options()`\n- LINK_LIBRARIES calls `target_link_libraries()`\n- PROPERTIES calls `set_target_properties()` with the supplied property-value pairs\n\nOne can mix calls to Gateau functions with CMake normal calls, however this may be at the\nexpanse of automated headers accounting and installation.\n\n### Installing a project\n\nMost of the work is performed at target creation. The actual `install` target is created\nthrough a simple call to `gateau_install_project()`, which will use the information\ngathered from previous calls to `gateau_configure()`, `gateau_add_library()` and\n`gateau_add_executable()`.\nConsequently, it should be placed near the end of your root CMakelists.txt, after all\nthe targets to be installed have been defined.\n\n### Generating documentation\n\n*Gateau* can produce Doxygen generated documentation with minimal setup and a single call\nto `gateau_build_documentation()`\n\n```\n# Generate documentation for this gateau project\ngateau_build_documentation(\n    [EXCLUDED_SYMBOLS symbol_regexes...]\n    [PREDEFINED_MACROS macros]\n    [INPUT_PATHS paths...]\n    [EXCLUDED_PATHS paths])\n```\n\n- EXCLUDED_SYMBOLS: list of symbols to exclude from the documentation, defaults to \"detail\"\n- PREDEFINED_MACROS: Preprocessor macros to define, with an optional value, when parsing files\n- INPUT_PATHS: input paths whose files should be parsed in addition to \"README.md\" and files\n  in the RELATIVE_HEADERS_DIRS list of source directories\n- EXCLUDED_PATHS: paths that should be excluded from the parsing\n\nExample use:\n\n```\ngateau_build_documentation(\n    EXCLUDED_SYMBOLS\n        MYPROJ_DETAIL*\n        detail*\n        _*\n    PREDEFINED_MACROS\n        MYPROJ_DECLARE_ENUM\n    EXCLUDED_PATHS\n        src/myproj/detail\n        src/myproj/3rdparty\n)\n```\n\n### Adding tests\n\n*Gateau* tries to make it easy to add testcases to a project. It has build in support\nfor three commonly used test libraries: [Google Test](https://github.com/google/googletest),\nQtTest, [Catch2](https://github.com/catchorg/Catch2) and [Doctest](https://github.com/onqtam/doctest).\n\nTo declare tests, one must first declare a head target and an optional associated provider\nthrough call to `gateau_setup_testing()`, then one can simply declare new test cases with\ncalls to `gateau_add_test()`.\n\n```\ngateau_setup_testing(\u003ctarget\u003e [GTEST|CATCH2|DOCTEST|QTTEST])\n\ngateau_add_test(\u003ctest_name\u003e [OPTIONS ACCEPTED BY gateau_add_executable()])\n```\n\nBy declaring a provider, said provider gets installed for you if required, test cases get\nlinked to the provider and the test cases are integrated to the CTest framework.\n\n### Other minor features\n\nSome of the Gateau modules export a few other useful functions.\n\n#### Grouping non source files into folders\n\n`gateau_other_files(category files...)` can be used to group the list of files into\na folder named \"category\". For tidy grouping in the tree view of an IDE.\n\nThis has not be tested apart from Qt Creator.\n\n#### Qt Related tools\n\nThe `GateauQtHelpers` module contains a few helpers to work with Qt related projects.\nThis has not been used and tested enough to warrant any documentation.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpalacaze%2Fgateau","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpalacaze%2Fgateau","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpalacaze%2Fgateau/lists"}