{"id":17427275,"url":"https://github.com/krmisha/makefile","last_synced_at":"2025-04-09T14:13:57.741Z","repository":{"id":40629722,"uuid":"213687599","full_name":"KRMisha/Makefile","owner":"KRMisha","description":"Cross-platform C++ Makefile project template","archived":false,"fork":false,"pushed_at":"2025-02-24T03:26:29.000Z","size":49,"stargazers_count":69,"open_issues_count":0,"forks_count":13,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T14:13:52.000Z","etag":null,"topics":["catch2","clang","clang-format","clang-tidy","compilation-database","compile-commands-json","conan","cpp","cross-platform","doxygen","gcc","makefile","makefile-template","testing","vcpkg"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KRMisha.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":"2019-10-08T15:52:25.000Z","updated_at":"2025-02-24T03:26:33.000Z","dependencies_parsed_at":"2023-11-01T04:25:04.086Z","dependency_job_id":"8a8382e6-7dea-49d1-9f9b-7fc26afff44d","html_url":"https://github.com/KRMisha/Makefile","commit_stats":{"total_commits":82,"total_committers":2,"mean_commits":41.0,"dds":"0.012195121951219523","last_synced_commit":"a6fe89c4e64c6d4ea699dd0c3168a7ca3a0790b2"},"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRMisha%2FMakefile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRMisha%2FMakefile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRMisha%2FMakefile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRMisha%2FMakefile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KRMisha","download_url":"https://codeload.github.com/KRMisha/Makefile/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054193,"owners_count":21039952,"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":["catch2","clang","clang-format","clang-tidy","compilation-database","compile-commands-json","conan","cpp","cross-platform","doxygen","gcc","makefile","makefile-template","testing","vcpkg"],"created_at":"2024-10-17T06:06:20.756Z","updated_at":"2025-04-09T14:13:57.709Z","avatar_url":"https://github.com/KRMisha.png","language":"Makefile","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg height=128 src=\"https://github.com/isocpp/logos/blob/master/cpp_logo.png?raw=true\" alt=\"C++ logo\" /\u003e\n\u003c/p\u003e\n\n# Makefile\n\nA cross-platform C++ Makefile for any project!\n\n## Features\n\n- **Cross-platform**: works on Linux, macOS, and Windows\n- **Automatic**: all source files are automatically found and compiled\n- **Efficient**: only the modified files are recompiled and their dependencies are automatically generated\n- **Debug and release** configurations\n- **Configurable**: easily add libraries or change compilation settings\n- **Package manager**-compatible (Conan and vcpkg)\n- **Testing** with the library of your choice\n- **Formatting** with clang-format\n- **Linting** with clang-tidy\n- **Generate documentation** from Doxygen comments\n- Built-in generation of `compile_commands.json`\n- Compatible with VS Code's [Makefile Tools extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools)\n\nSee the [table of contents](#table-of-contents) at the end.\n\n## Prerequisites\n\n### Make \u0026 GCC\n\n\u003e Alternatively, Clang can be used instead of GCC (see [here](#using-a-different-compiler)). The instructions below will focus on GCC.\n\n- Linux:\n    - Debian/Ubuntu: `sudo apt install build-essential`\n    - Fedora: `sudo dnf install make gcc-c++`\n    - openSUSE: `sudo zypper install make gcc-c++`\n    - Arch Linux: `sudo pacman -S make gcc`\n- macOS:\n    1. Run the following command: `xcode-select --install`\n    2. In the window which pops up, click \"Install\" and follow the instructions.\n- Windows:\n    1. Install MinGW-w64 from [WinLibs.com](https://winlibs.com/).\n    2. Add the path to MinGW-64's `bin` directory to Windows's system `PATH` environment variable.\n        \u003e You will need to use `mingw32-make` instead of `make` each time the `make` command is used in this README.\n    3. Install Git Bash by installing [Git for Windows](https://git-scm.com/downloads).\n        \u003e You will need to use **Git Bash** instead of PowerShell or `cmd.exe` each time the `make` command is used in this README.\n\n### Optional dependencies\n\n- For formatting: [clang-format](https://clang.llvm.org/docs/ClangFormat.html)\n- For linting: [clang-tidy](https://clang.llvm.org/extra/clang-tidy/)\n- For generating documentation: [Doxygen](https://www.doxygen.nl/index.html) and [Graphviz](https://graphviz.org/)\n\n## Usage\n\n### Overview of commands\n\n```console\n$ make help\nUsage: make target... [options]...\n\nTargets:\n  all             Build executable and tests (debug configuration by default) (default target)\n  run             Build and run executable (debug configuration by default)\n  test            Build and run tests (debug configuration by default)\n  copyassets      Copy assets to executable directory for selected platform and configuration\n  cleanassets     Clean assets from executable directories (all platforms)\n  clean           Clean build directory (all platforms)\n  compdb          Generate JSON compilation database (compile_commands.json)\n  format          Format source code using clang-format\n  format-check    Check that source code is formatted using clang-format\n  lint            Lint source code using clang-tidy\n  lint-fix        Lint and fix source code using clang-tidy\n  docs            Generate documentation with Doxygen\n  help            Print this information\n  printvars       Print Makefile variables for debugging\n\nOptions:\n  release=1       Run target using release configuration rather than debug\n\nNote: the above options affect the following targets: all, run, test, copyassets, compdb, printvars\n```\n\n### Building\n\n```sh\nmake\n```\n\nThis will compile the executable (and optionally, tests) and output it inside the current `bin` directory (`build/\u003cplatform\u003e/\u003cconfiguration\u003e/bin`). This is equivalent to `make all`.\n\n#### Using a different compiler\n\nBy default, all builds use GCC. To use another compiler, override the `CXX` variable when invoking `make`. For example, to use Clang:\n\n```sh\nmake CXX=clang++\n```\n\n### Running\n\n```sh\nmake run\n```\n\nThis will run the executable, rebuilding it first if it was out of date. The working directory will be the executable's directory, i.e. the current `bin` directory.\n\n### Testing\n\nIf your project contains tests, you can run them with the following command:\n\n```sh\nmake test\n```\n\nThis will run the test executable, rebuilding it first if it was out of date. The working directory will be the current `bin` directory.\n\nSee [here](#setting-up-tests) for information on setting up tests for your project.\n\n### Assets\n\n#### Copying assets\n\nTo add files to be copied next to the executable's output location, simply add them to the `assets` directory. Then, use the following command:\n\n```sh\nmake copyassets\n```\n\nThis will copy the contents of `assets` to the current `bin` directory, preserving their folder structure.\n\n#### Platform-specific assets\n\nIf you have certain assets which you wish to only copy for certain platforms, you can do the following:\n\n1. Create an `assets_os/\u003cplatform\u003e` directory at the root of the project. The `\u003cplatform\u003e` directory should be named either `linux`, `macos`, or `windows` based on the desired platform for the assets.\n2. Inside this new directory, add all the assets to be copied only for this platform.\n\nYou can then use the `make copyassets` command as usual.\n\nThe files copied to the current `bin` directory will be the combination of the files in `assets` and `assets_os`, with files in `assets_os` overwriting those in `assets` in case of naming clashes.\n\n\u003e The `assets_os` directory is useful for holding Windows DLLs which need to be copied next to the executable (using `assets_os/windows`).\n\n#### Cleaning assets\n\n```sh\nmake cleanassets\n```\n\nThis will remove all the files in all `bin` directories, except for executables and tests.\n\n### Cleaning\n\n```sh\nmake clean\n```\n\nThis will remove the entire `build` directory.\n\n### Options\n\nOptions can be specified when building, running, testing, and copying assets. These will modify the settings used to build the executable (and optionally, tests) and affect what is considered the current `bin` directory when running a command.\n\n#### Release configuration\n\nBy default, builds use the debug configuration. To build for release (including optimizations), add the `release=1` option when invoking `make`:\n\n```sh\nmake release=1\n```\n\nTo use the `release` version of the executable, `release=1` must also be specified when running or when copying assets. For example:\n\n```sh\nmake copyassets run release=1\n```\n\n### Generating a JSON compilation database\n\nSome language servers and tools, like clangd or clang-tidy, rely on a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) (`compile_commands.json`). To generate this file, use the following command:\n\n```sh\nmake compdb\n```\n\nThis will create the compilation database in `build/compile_commands.json`. You should rerun this command any time you add files to your project.\n\n### Formatting\n\n```sh\nmake format\n```\n\nThis will format all files (both sources and headers) using clang-format according to the options set in `.clang-format`.\n\nTo only verify if the files are correctly formatted, use the following command:\n\n```sh\nmake format-check\n```\n\nThis will return exit code `1` if any files are not formatted.\n\n### Linting\n\n```sh\nmake lint\n```\n\nThis will lint all files (both sources and headers) using clang-tidy according to the options set in `.clang-tidy`. This will return exit code `1` if any files have lint errors.\n\nTo apply the suggested fixes to errors found by clang-tidy, use the following command:\n\n```sh\nmake lint-fix\n```\n\n### Generating documentation\n\nDocumentation can be generated from [documentation comments](https://www.doxygen.nl/manual/docblocks.html) using Doxygen.\n\n#### First-time use\n\n1. Create a new `docs` directory at the root of the project.\n2. Generate a new Doxyfile in `docs/Doxyfile`:\n\n    ```sh\n    cd docs\n    doxygen -g\n    ```\n\n    Or, to use the graphical wizard instead:\n\n    ```sh\n    cd docs\n    doxywizard\n    ```\n\n#### Updating the documentation\n\n```sh\nmake docs\n```\n\nThis will generate the documentation according to the rules found in `docs/Doxyfile` and output it in the `docs` directory.\n\n## Adding libraries\n\nThere are several ways to add a library to your project.\n\n### Using a package manager\n\nFor more complex projects, using a package manager is the recommended way to add libraries. This method ensures that your libraries are managed consistently across platforms.\n\n#### [Conan](https://conan.io/)\n\nYou can integrate Conan with the Makefile by using the [MakeDeps generator](https://docs.conan.io/2/reference/tools/gnu/makedeps.html).\n\n1. Install Conan using `pip`:\n\n    ```sh\n    pip install conan\n    ```\n\n2. Create a Conan profile:\n\n    ```sh\n    conan profile detect --force\n    ```\n\n    The path of the generated profile can be found using `conan profile path default`. You can edit this file and set `compiler.cppstd` to your desired C++ standard (e.g. `compiler.cppstd=20`).\n\n    Note: on Windows, you should modify the default profile to use MinGW (GCC) instead of MSVC. Make the following changes to the default profile:\n\n    ```ini\n    compiler=gcc\n    compiler.cppstd=\u003cdesired C++ standard, e.g. 20\u003e\n    compiler.libcxx=libstdc++11\n    compiler.version=\u003cinstalled GCC version, e.g. 13\u003e\n    ```\n\n    The `compiler.runtime` setting should be removed, as it is specific to MSVC.\n\n3. Create a `conanfile.txt` at the root of the project:\n\n    ```ini\n    [requires]\n    # Add dependencies...\n\n    [generators]\n    MakeDeps\n    ```\n\n4. Edit the Makefile:\n\n    ```makefile\n    # Includes\n    INCLUDE_DIR =\n    INCLUDES = $(addprefix -I,$(SRC_DIR) $(INCLUDE_DIR)) $(CONAN_INCLUDE_DIRS)\n    TEST_INCLUDES = -I$(TEST_DIR)\n\n    # C preprocessor settings\n    CPPFLAGS = $(INCLUDES) -MMD -MP $(CONAN_DEFINES)\n\n    [...]\n\n    # Linker flags\n    LDFLAGS = $(CONAN_LIB_DIRS)\n    TEST_LDFLAGS =\n\n    # Libraries to link\n    LDLIBS = $(CONAN_LIBS_\u003cLIBRARY_NAME\u003e) $(CONAN_SYSTEM_LIBS)\n    TEST_LDLIBS =\n\n    [...]\n\n    # Object, bin, and Conan directories\n    OBJ_DIR := $(BUILD_DIR)/obj\n    BIN_DIR := $(BUILD_DIR)/bin\n    CONAN_DIR := $(BUILD_DIR)/conan\n\n    # Conan\n    ifneq ($(MAKECMDGOALS),clean)\n        CONAN_DEFINE_FLAG = -D\n        CONAN_INCLUDE_DIR_FLAG = -isystem\n        CONAN_LIB_DIR_FLAG = -L\n        CONAN_BIN_DIR_FLAG = -L\n        CONAN_LIB_FLAG = -l\n        CONAN_SYSTEM_LIB_FLAG = -l\n        include $(CONAN_DIR)/conandeps.mk\n    endif\n\n    [...]\n\n    # Generate Conan dependencies\n    $(CONAN_DIR)/conandeps.mk: conanfile.txt\n        @echo \"Generating: $@\"\n        @mkdir -p $(@D)\n        @conan install . --output-folder=$(CONAN_DIR) --build=missing\n\n    # Build executable\n    [...]\n    ```\n\n`$(CONAN_LIBS_\u003cLIBRARY_NAME\u003e)` should be repeated for each dependency, replacing `\u003cLIBRARY_NAME\u003e` with the library's name. Libraries which depend on other libraries should be listed before the libraries they depend on.\n\nSee [this gist](https://gist.github.com/KRMisha/99099d3c38efb038ff3b39e3c1bd6880) for an example of the modifications to make.\n\n#### [vcpkg](https://vcpkg.io/en/)\n\nYou can integrate vcpkg with the Makefile by using the [manual integration](https://learn.microsoft.com/en-us/vcpkg/users/buildsystems/manual-integration).\n\n1. Add vcpkg as a submodule:\n\n    ```sh\n    git submodule add https://github.com/Microsoft/vcpkg.git\n    ```\n\n2. Run the bootstrap script to build vcpkg:\n\n    ```sh\n    ./vcpkg/bootstrap-vcpkg.sh\n    ```\n\n3. Create a `vcpkg.json` at the root of the project:\n\n    ```jsonc\n    {\n        \"dependencies\": [\n            // Add dependencies...\n        ]\n    }\n    ```\n\n4. Install the dependencies listed in `vcpkg.json`:\n\n    ```sh\n    ./vcpkg/vcpkg install\n    ```\n\n    Note: on Windows, you should set the target and host triplet to the [MinGW triplet](https://learn.microsoft.com/en-us/vcpkg/users/platforms/mingw). This can be done by setting the following environment variables *before* running the previous command:\n\n    ```sh\n    export VCPKG_DEFAULT_TRIPLET=x64-mingw-static\n    export VCPKG_DEFAULT_HOST_TRIPLET=x64-mingw-static\n    ```\n\n5. Edit the Makefile:\n\n    ```makefile\n    # Platform-specific settings\n    ifeq ($(OS),windows)\n        [...]\n\n        # Windows-specific settings\n        INCLUDES += -isystem vcpkg_installed/x64-mingw-static/include\n        LDFLAGS += -Lvcpkg_installed/x64-mingw-static/lib\n        LDLIBS += # Add libraries with -l...\n    else ifeq ($(OS),macos)\n        # macOS-specific settings\n        INCLUDES += -isystem vcpkg_installed/x64-osx/include\n        LDFLAGS += -Lvcpkg_installed/x64-osx/lib\n        LDLIBS += # Add libraries with -l...\n    else ifeq ($(OS),linux)\n        # Linux-specific settings\n        INCLUDES += -isystem vcpkg_installed/x64-linux/include\n        LDFLAGS += -Lvcpkg_installed/x64-linux/lib\n        LDLIBS += # Add libraries with -l...\n    endif\n    ```\n\nSee [this gist](https://gist.github.com/KRMisha/7c19c73b2833f54f2d84bc7bb3ae788c) for an example of the modifications to make.\n\n### Header-only library\n\nHeader-only libraries are composed solely of header files. This way, no separate compilation or linking is necessary.\n\n1. If this is the first library you are adding, create a new `external` directory at the root of the project.\n2. Inside the `external` directory, create a `\u003clibrary-name\u003e` sudirectory to contain the library's header files.\n3. Download the library's header files and add them to `external/\u003clibrary-name\u003e`.\n4. Add the library's header files to the preprocessor's search path: add `-isystem external/\u003clibrary-name\u003e` to the `INCLUDES` variable (line 28 of the Makefile).\n\n### Library installed system-wide\n\nSome libraries can be installed system-wide, using your system's package manager. For example:\n\n- On macOS, using [Homebrew](https://brew.sh/) or [MacPorts](https://www.macports.org/)\n- On Debian/Ubuntu, using `apt`\n- On Fedora, using `dnf`\n- On openSUSE, using `zypper`\n- On Arch Linux, using `pacman`\n\nThese system package managers install dependencies in a default system-wide directory, such as `/usr/lib` and `/usr/include` on Linux. Some important system-wide libraries may also come preinstalled on your system.\n\nRelying on a system package manager for your libraries can make it less straightforward for other developers using a different platform to start working on your project. Nevertheless, this can be a quick way for you to start using a library, especially if this library is already required by the system.\n\n1. Use your system package manager to install the library's development package. Often, development packages will have the `-dev` or `-devel` suffix.\n2. Link with the library: add `-l\u003clibrary-name\u003e` to the `LDLIBS` variable (line 44 of the Makefile).\n\n    Depending on the library, more than one library name may need to be added with the `-l` option. Refer to your library's documentation for the names to use with the `-l` option in this step.\n\n    Note: on macOS, you may need to link your library using `-framework` rather than `-l`.\n\n### Library built from source\n\nAlternatively, if a library is not available in any package manager, you can build it from source or download its compiled artifacts and add them to your project.\n\n1. If this is the first library you are adding, create a new `external` directory at the root of the project.\n2. Inside the `external` directory, create a `\u003clibrary-name\u003e` sudirectory to contain the library's files.\n3. Build or download the library's compiled files and add them to `external/\u003clibrary-name\u003e`.\n\n    You may instead prefer to add the library as a Git submodule inside the `external` directory to make updates easier.\n\n4. Add the library's header files to the preprocessor's search path: add `-isystem /\u003clibrary-name\u003e/include` to the `INCLUDES` variable (line 28 of the Makefile).\n5. Add the library's compiled files to the linker's search path: add `-Lexternal/\u003clibrary-name\u003e/lib` to the `LDFLAGS` variable (line 40 of the Makefile).\n6. Link with the library: add `-l\u003clibrary-name\u003e` to the `LDLIBS` variable (line 44 of the Makefile).\n\n    Depending on the library, more than one library name may need to be added with the `-l` option. Refer to your library's documentation for the names to use with the `-l` option in this step.\n\n    Note: on macOS, you may need to link your library using `-framework` rather than `-l`.\n\nNote that the folder structure inside `external/\u003clibrary-name\u003e` will vary from one library to the next. In the above instructions:\n\n- The `include` subdirectory refers to a directory containing all of the library's header files.\n- The `lib` subdirectory refers to a directory containing all of the library's compiled files (e.g. `.so`, `.a`, `.lib`, `.framework`, etc.). If you have chosen to build the library from source, you should copy the output of the compiled library to the `lib` directory.\n\nThese directories may be named differently: refer to your library's documentation for more information.\n\n## Setting up tests\n\n1. Create a new `tests` directory at the root of the project to hold your test source files.\n2. Pick your preferred C++ testing framework. For example:\n    - [Catch2](https://github.com/catchorg/Catch2) (recommended)\n    - [doctest](https://github.com/doctest/doctest)\n    - [GoogleTest](https://github.com/google/googletest)\n3. Make the testing framework available to your project using one of the methods described in [adding libraries](#adding-libraries).\n\n    Using a package manager such as [Conan](#conan) or [vcpkg](#vcpkg) is the recommended way to add this library.\n\n    However, do not add the flags for the library to the `INCLUDES`, `LDFLAGS`, or `LDLIBS` variables. This is because only tests should link against the test framework library, not the main executable. See the next step for how to do this.\n\n    \u003e For the simplest possible setup, you may instead prefer to use doctest, which is available as a [single header file](#header-only-library).\n\n4. Add the necessary flags to link with the library, as described in your chosen method for adding libraries, but with the following replacements:\n\n    - Use `TEST_INCLUDES` (line 29) instead of `INCLUDES` (line 28) to add the library's header files to the preprocessor's search path.\n    - Use `TEST_LDFLAGS` (line 41) instead of `LDFLAGS` (line 40) to add the library's compiled files to the linker's search path (if applicable).\n    - Use `TEST_LDLIBS` (line 45) instead of `LDLIBS` (line 44) to link with the library (if applicable).\n\n    The `TEST_INCLUDES`, `TEST_LDFLAGS`, and `TEST_LDLIBS` variables apply only to tests. These are appended to the regular `INCLUDES`, `LDFLAGS`, and `LDLIBS` variables when building the tests.\n\n5. Add at least one test source file to the `tests` directory.\n\nSee [this gist](https://gist.github.com/KRMisha/7f796201167780f7e5ae2217445836f2) for an example using Catch2 with Conan.\n\nOnce this is done, running `make` (or `make all`) will now build both the executable and tests. To build and run the tests, use `make test`.\n\n\u003e The test executable is built from all the source files under both `tests` and `src`, except for `src/main.cpp`. This means you can test any functions defined in `src`, as long as these are not defined in `src/main.cpp`.\n\n## Configuration\n\n### Frequently changed settings\n\nThe following table presents an overview of the most commonly changed settings of the Makefile:\n\n| Configuration                                                                                        | Variable                                       | Line       |\n|------------------------------------------------------------------------------------------------------|------------------------------------------------|------------|\n| Change the output executable name                                                                    | `EXEC`                                         | 6          |\n| Select the C++ compiler (e.g. `g++` or `clang++`)                                                    | `CXX`                                          | 35         |\n| Add preprocessor settings (e.g. `-D\u003cmacro-name\u003e`)                                                    | `CPPFLAGS`                                     | 32         |\n| Change C++ compiler settings (useful for setting the C++ standard version)                           | `CXXFLAGS`                                     | 36         |\n| Add/remove compiler warnings                                                                         | `WARNINGS`                                     | 37         |\n| Add includes for libraries common to all platforms (e.g. `-isystem external/\u003clibrary-name\u003e/include`) | `INCLUDES`                                     | 28         |\n| Add linker flags for libraries common to all platforms (e.g. `-Lexternal/\u003clibrary-name\u003e/lib`)        | `LDFLAGS`                                      | 40         |\n| Add libraries common to all platforms (e.g. `-l\u003clibrary-name\u003e`)                                      | `LDLIBS`                                       | 44         |\n| Add includes/linker flags/libraries for specific platforms                                           | `INCLUDES`, `LDFLAGS`, `LDLIBS`                | 61-80      |\n| Add additional includes/linker flags/libraries for tests                                             | `TEST_INCLUDES`, `TEST_LDFLAGS`, `TEST_LDLIBS` | 29, 41, 45 |\n\nAll the configurable options are defined between lines 1-80. For most uses, the Makefile should not need to be modified beyond line 80.\n\n### Platform-specific library configuration\n\nThe section on [adding libraries](#adding-libraries) explains how to add a library using the common `INCLUDES`, `LDFLAGS`, and `LDLIBS` variables which are shared between all platforms. However, in some cases, a library may need to be linked differently by platform. Examples of such platform-specific library configurations include:\n\n- Adding a library needed only for code enabled on a certain platform.\n- Using `-framework` over `-l` to link a library on macOS.\n- Specifying a different path for a library's compiled files with `-L`.\n\nThe Makefile is designed to support these kinds of platform-specific configurations alongside one another.\n\nLines 61-80 of the Makefile contain platform-specific `INCLUDES`, `LDFLAGS`, and `LDLIBS` variables which should be used for this purpose. To add a library for a certain platform, simply add the options to the variables under the comment indicating the platform.\n\n\u003e The common `INCLUDES` (line 28), `LDFLAGS` (line 40), and `LDLIBS` (line 44) variables should only contain options which are identical for all platforms. Any platform-specific options should instead be specified using lines 61-80.\n\n### Separate directories for headers and sources\n\nBy default, your project's header files should be placed under `src`, next to their associated source files. Headers which are only used by tests should be placed under `tests`.\n\nHowever, if you wish to place your header files in a separate directory from your source files, you can do so by setting the `INCLUDE_DIR` variable (line 27 of the Makefile):\n\n```makefile\nINCLUDE_DIR = include\n```\n\nThis will add the `include` directory to the preprocessor's search path.\n\nThis can be useful when developing a library: in this configuration, your library's public headers should be placed under `include`, and its private headers under `src`.\n\n## Project layout\n\n```text\n.\n├── assets\n│   └── \u003cassets\u003e\n├── assets_os\n│   └── linux | macos | windows\n│       └── \u003cassets\u003e\n├── build\n│   └── linux | macos | windows\n│       └── debug | release\n│           ├── bin\n│           │   ├── executable\n│           │   └── \u003cassets\u003e\n│           └── obj\n│               ├── **/*.o\n│               └── **/*.d\n├── docs\n│   ├── Doxyfile\n│   └── **/*.html\n├── include (optional)\n│   └── **/*.h\n├── src\n│   ├── main.cpp\n│   ├── **/*.cpp\n│   └── **/*.h\n├── tests\n│   ├── **/*.cpp\n│   └── **/*.h\n├── .clang-format\n├── .clang-tidy\n├── .gitattributes\n├── .gitignore\n├── Makefile\n└── README.md\n```\n\n## License\n\n[MIT](https://opensource.org/licenses/MIT)\n\nTo comply with the terms of the MIT license in your project, simply copy-pasting the entire contents of the provided [`LICENSE`](LICENSE) file as a comment at the top of the Makefile is sufficient. By doing so, you do not need to include the `LICENSE` file directly since it is is now contained in the Makefile. You can then reuse the `LICENSE` filename for your own license if you wish.\n\n## Table of contents\n\n- [Features](#features)\n- [Prerequisites](#prerequisites)\n    - [Make \\\u0026 GCC](#make--gcc)\n    - [Optional dependencies](#optional-dependencies)\n- [Usage](#usage)\n    - [Overview of commands](#overview-of-commands)\n    - [Building](#building)\n        - [Using a different compiler](#using-a-different-compiler)\n    - [Running](#running)\n    - [Testing](#testing)\n    - [Assets](#assets)\n        - [Copying assets](#copying-assets)\n        - [Platform-specific assets](#platform-specific-assets)\n        - [Cleaning assets](#cleaning-assets)\n    - [Cleaning](#cleaning)\n    - [Options](#options)\n        - [Release configuration](#release-configuration)\n    - [Generating a JSON compilation database](#generating-a-json-compilation-database)\n    - [Formatting](#formatting)\n    - [Linting](#linting)\n    - [Generating documentation](#generating-documentation)\n        - [First-time use](#first-time-use)\n        - [Updating the documentation](#updating-the-documentation)\n- [Adding libraries](#adding-libraries)\n    - [Using a package manager](#using-a-package-manager)\n        - [Conan](#conan)\n        - [vcpkg](#vcpkg)\n    - [Header-only library](#header-only-library)\n    - [Library installed system-wide](#library-installed-system-wide)\n    - [Library built from source](#library-built-from-source)\n- [Setting up tests](#setting-up-tests)\n- [Configuration](#configuration)\n    - [Frequently changed settings](#frequently-changed-settings)\n    - [Platform-specific library configuration](#platform-specific-library-configuration)\n    - [Separate directories for headers and sources](#separate-directories-for-headers-and-sources)\n- [Project layout](#project-layout)\n- [License](#license)\n- [Table of contents](#table-of-contents)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrmisha%2Fmakefile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrmisha%2Fmakefile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrmisha%2Fmakefile/lists"}