{"id":15394228,"url":"https://github.com/xyproto/cxx","last_synced_at":"2025-04-11T19:13:13.686Z","repository":{"id":37377280,"uuid":"114762611","full_name":"xyproto/cxx","owner":"xyproto","description":":electric_plug: Configuration-free utility for building, testing and packaging executables written in C++. Can auto-detect compilation flags based on includes, via the package system and pkg-config.","archived":false,"fork":false,"pushed_at":"2024-07-23T10:45:07.000Z","size":8820,"stargazers_count":120,"open_issues_count":2,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-25T15:09:05.360Z","etag":null,"topics":["arch-linux","auto-detection","bsd","c","c-plus-plus","clang-format","cli","cmake","cpp","cpp17","cpp20","cxx","cxx20","freebsd","linux","ninja","qmake","scons","void-linux"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xyproto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["xyproto"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2017-12-19T12:28:05.000Z","updated_at":"2025-03-04T12:49:45.000Z","dependencies_parsed_at":"2024-02-19T09:35:10.819Z","dependency_job_id":"85400ef6-f925-497b-9d08-a9a5ba0d5e8c","html_url":"https://github.com/xyproto/cxx","commit_stats":{"total_commits":914,"total_committers":4,"mean_commits":228.5,"dds":0.03282275711159732,"last_synced_commit":"0968cb42294806b97524c9e4247282ab5ca8712a"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyproto%2Fcxx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyproto%2Fcxx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyproto%2Fcxx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyproto%2Fcxx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xyproto","download_url":"https://codeload.github.com/xyproto/cxx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248465344,"owners_count":21108244,"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":["arch-linux","auto-detection","bsd","c","c-plus-plus","clang-format","cli","cmake","cpp","cpp17","cpp20","cxx","cxx20","freebsd","linux","ninja","qmake","scons","void-linux"],"created_at":"2024-10-01T15:22:31.959Z","updated_at":"2025-04-11T19:13:13.661Z","avatar_url":"https://github.com/xyproto.png","language":"Python","funding_links":["https://github.com/sponsors/xyproto"],"categories":[],"sub_categories":[],"readme":"# CXX\n\n[![Standard](https://img.shields.io/badge/C%2B%2B-20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n\nMake modern C++ easier to deal with.\n\nHave you ever had a single `main.cpp` file that you just want to compile, without having to make sure the order of flags are correct and ideally without having to provide any flags at all?\n\n`cxx` may fit your use case, provided you have `scons`, `python` and all required libraries for your project installed.\n\nIt should be possible to compile most of the examples in the `examples` directory, simply by running `cxx` in each directory.\n\nUsing `cxx` is simple:\n\n* `cxx` builds a project\n* `cxx fmt` formats the source code\n* `cxx debug` performs a debug build\n* `cxx cmake` generates a `CMakeLists.txt` file that is compatible with many IDEs.\n* `cxx pro` generates a project file that is compatible with QtCreator.\n* `cxx cmake ninja` generates a `CMakeLists.txt` file and then builds the project using `ninja` (and `ccache`, if available).\n* `cxx ninja` just builds the project using a `CMakeLists.txt` file and `ninja` (and `ccache`, if available).\n* `cxx export` generates build files for users without cxx.\n\nNo configuration files are needed, but the projects needs to either be very simple (a single `main.cpp`) or have a `cxx`-friendly directory structure.\n\nThe auto-detection of external libraries and headers relies on them being included in the main source file.\n\nTested on Arch Linux, FreeBSD, Ubuntu, macOS w/Homebrew, Void Linux and NetBSD. Docker images and Vagrant configuration files are available in the `tests` directory. Please submit a pull request if you have improvements for your platform!\n\nSeveral examples are included in the `examples` directory. These mostly center around everything you would need to create a game in C++20: OpenGL, SDL2, Vulkan, Audio etc, but also includes examples for GTK 4, Qt 6, X11 and Windows (the example should build and run on Linux, using `wine`).\n\nThe target audience is programmers that don't want to fiddle with makefiles, CMake etc, but want to either try out a feature in C++20, learn modern C++ or create a demoscene demo or a game.\n\nAs much as possible is auto-detected. As long as the right packages are installed, and includes are specified in the main source file, all dependencies, libraries and build flags should be handled automatically.\n\n`cxx` provides a way to structure your C++ code, test and debug your source files. It also makes it easy for Linux (or Homebrew) packagers to package your project, and for users to build and install it.\n\nIf you're an experienced C or C++ user and wish to write and distribute a C++ **library** (as opposed to an executable), just using CMake might be a better fit.\n\n(This repository was created three years before [dtolnay/cxx](https://github.com/dtolnay/cxx)).\n\n## Packaging status\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/cxx.svg)](https://repology.org/project/cxx/versions)\n\n## Installation\n\nIf `cxx` is available by using your favorite package manager, that's usually the best way.\n\n### Manual installation\n\nFirst install `cxx`, so that it is in the path. Here is one way, using `git clone`, GNU Make and `sudo`:\n\n    git clone https://github.com/xyproto/cxx\n    cd cxx\n    make\n    sudo make install\n\n### Debian-based distros\n\nFor Debian or Ubuntu, these dependencies are recommended, for building CXX and most of the examples:\n\n    build-essential figlet freeglut3-dev g++-mingw-w64-x86-64 git gtk+3-dev libboost-all-dev libc-dev libglew-dev libglibmm-2.4-dev libsdl2-dev libsfml-dev make mesa-common-dev qtbase5-dev qt5-default qtdeclarative5-dev scons python3 apt-utils apt-file libconfig++-dev libconfig++ libopenal-dev libglfw3-dev libvulkan-dev libglm-dev libsdl2-mixer-dev libboost-system-dev libfcgi-dev\n\n### FreeBSD\n\nFor FreeBSD, here is one way of installing only the basic dependencies and CXX:\n\n    pkg install -y bash git gmake pkgconf python3 scons\n    git clone https://github.com/xyproto/cxx\n    cd cxx\n    gmake\n\nThen as root:\n\n    gmake install\n\n### NetBSD\n\nOne way of installing CXX and also the libraries needed by most of the example projects:\n\n    pkgin -y install bash git gmake pkgconf python37 SDL2 SDL2_image SDL2_mixer SDL2_net SDL2_ttf docker freeglut gcc7 glew glm glut openal qt5 scons boost fcgi\n    test -d cxx \u0026\u0026 (cd cxx; git -c http.sslVerify=false pull origin main) || git -c http.sslVerify=false clone 'https://github.com/xyproto/cxx'\n    gmake -C cxx install\n\n### Void Linux\n\nInstalling CXX and the libraries needed by most of the example projects:\n\n    xbps-install -v -Sy SDL2-devel SDL2_mixer-devel SFML-devel boost-devel figlet gcc git glew-devel gtk+3-devel libconfig++-devel libfreeglut-devel libopenal-devel make pkg-config python3 qt5-devel scons fcgi\n    git clone https://github.com/xyproto/cxx \u0026\u0026 cd cxx \u0026\u0026 make install\n\n### Arch Linux\n\nJust install `cxx` from AUR.\n\n## Example Use\n\n### Try out CXX and a small program that uses features from C++20\n\nCreate a **main.cpp** file:\n\n```c++\n#include \u003ccstdlib\u003e\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n#include \u003costream\u003e\n#include \u003cstring\u003e\n\nusing namespace std::string_literals;\n\nclass Point {\npublic:\n    double x;\n    double y;\n    double z;\n};\n\nstd::ostream\u0026 operator\u003c\u003c(std::ostream\u0026 output, const Point\u0026 p)\n{\n    using std::setfill;\n    using std::setw;\n    output \u003c\u003c \"{ \"s \u003c\u003c setfill(' ') \u003c\u003c setw(3) \u003c\u003c p.x \u003c\u003c \", \"s \u003c\u003c setfill(' ') \u003c\u003c setw(3) \u003c\u003c p.y\n           \u003c\u003c \", \"s \u003c\u003c setfill(' ') \u003c\u003c setw(3) \u003c\u003c p.z \u003c\u003c \" }\"s;\n    return output;\n}\n\nPoint operator+(const Point\u0026 a, const Point\u0026 b)\n{\n    return Point { .x = a.x + b.x, .y = a.y + b.y, .z = a.z + b.z };\n}\n\nPoint operator*(const Point\u0026 a, const Point\u0026 b)\n{\n    return Point { .x = a.x * b.x, .y = a.y * b.y, .z = a.z * b.z };\n}\n\nint main(int argc, char** argv)\n{\n    // designated initializers\n    Point p1 { .x = 1, .y = 2, .z = 3 };\n    Point p2 { .y = 42 };\n\n    using std::cout;\n    using std::endl;\n\n    cout \u003c\u003c \"     p1 = \" \u003c\u003c p1 \u003c\u003c endl;\n    cout \u003c\u003c \"     p2 = \" \u003c\u003c p2 \u003c\u003c endl;\n    cout \u003c\u003c \"p1 + p2 = \" \u003c\u003c p1 + p2 \u003c\u003c endl;\n    cout \u003c\u003c \"p1 * p2 = \" \u003c\u003c p1 * p2 \u003c\u003c endl;\n\n    return EXIT_SUCCESS;\n}\n```\n\nThen build the project with just:\n\n    cxx\n\nRebuilding can be done with:\n\n    cxx rebuild\n\nBoth building and running can be done with:\n\n    cxx run\n\nIf you wish to optimize the program, running it in a way that also records profiling information can be done with:\n\n    cxx rec\n\nThe next time the project is built, the profiling information is used to optimize the program further:\n\n    cxx\n\n## Other commands\n\n#### Building files ending with `_test.cpp`, then running them\n\n    cxx test\n\n#### Cleaning\n\n    cxx clean\n\n#### Building with `clang++` instead of `g++`:\n\n    cxx clang\n\n#### Building a specific directory\n\n    cxx -C examples/hello\n\n#### Installing on the local system, using sudo:\n\n    sudo PREFIX=/usr cxx install\n\nEither `main.cpp` or the C++ source files in the current directory will be used when building with `cxx`.\n\n#### Packaging a project into `$pkgdir`:\n\n    DESTDIR=\"$pkgdir\" PREFIX=/usr cxx install\n\n#### Packaging a project into a directory named `pkg`:\n\n    cxx pkg\n\n#### Build a small executable:\n\n    cxx small\n\n#### Build an executable with optimization flags turned on:\n\n    cxx opt\n\n#### Strict compilation flags (complains about all things):\n\n    cxx strict\n\n#### Sloppy compilation flags (will ignore all warnings):\n\n    cxx sloppy\n\n#### Get the current version:\n\n    cxx version\n\n## Directories\n\n* The top level directory, or `src/`, or a custom directory can contain at least one source file containing a `main` function.\n* The name of the produced executable will be the same as the name of the parent directory, or `main` if the parent directory is `src`.\n* `include/` can contain all include files belonging to the project.\n* `common/` can contain all source code that can be shared between multiple executables.\n* `img/` can contain images.\n* `shaders/` can contain shaders.\n* `data/` can contain all other data files needed by the program.\n* `shared/` can contain all files optionally needed by the program, like example data.\n\n## Testing\n\n* All source files, except the one containing the `main` function, can have a corresponding `_test` file. For instance: `quaternions.cc` and `quaternions_test.cc`.\n* When running `cxx test`, the `_test.*` files will be compiled and run.\n* `*_test.*` files must each contain a `main` function.\n\n## Defines\n\nThese defines are passed to the compiler, if the corresponding paths exist (or will exist, when packaging):\n\n* `DATADIR` is defined as `./data` or `../data` (when developing) and `$PREFIX/share/application_name/data` (at installation time)\n* `IMGDIR` is defined as `./img` or `../img` (when developing) and `$PREFIX/share/application_name/img` (at installation time)\n* `SHADERDIR` is defined as `./shaders` or `../shaders` (when developing) and `$PREFIX/share/application_name/shaders` (at installation time)\n* `SHAREDIR` is defined as `./share` or `../share` (when developing) and `$PREFIX/share/application_name` (at installation time)\n* `RESOURCEDIR` is defined as `./resources` or `../resources` (when developing) and `$PREFIX/share/application_name/resources` (at installation time)\n* `RESDIR` is defined as `./res` or `../res` (when developing) and `$PREFIX/share/application_name/res` (at installation time)\n\n(`application_name` is just an example).\n\nThis makes it easy to have an `img`, `data` or `resources` directory where files can be found and used both at development and at installation-time.\n\nSee `examples/sdl2` and `examples/win64crate` for examples that uses `IMGDIR`.\n\nSee `examples/mixer` for an example that uses `RESOURCEDIR`.\n\nAn alternative method to using defines (defined with `-D` when building) is to use something like `SDL_GetBasePath()`. Example: [`res_path.h`](https://github.com/libSDL2pp/TwinklebearDev-Lessons-libSDL2pp/blob/sdl2pp/include/res_path.h).\n\n## Features and limitations\n\n* **No configuration files are needed**, as long as the *CXX* directory structure is followed.\n* **Auto-detection** of include, define and library flags, based on which files are included from `/usr/include`, using **`pkg-config`**. It also uses system-specific ways of attempting to detect which packages provides which compilation flags. Not all libraries, include files and cxxflags can be auto-detected yet, but more are to be added.\n* Built-in support for testing, clang, debug builds and only rebuilding files that needs to be rebuilt.\n* Does not use a `build` directory, it's okay that the `main` executable ends up in the root folder of the project. `main.cpp` can be placed in the root folder of the project, or in its own directory.\n* Should be easy to port to other systems that also has a package manager and pkg-config (or equivalent way to discover build flags).\n* Your include files are expected to be found in `./include` or `../include`.\n* Source files used by multiple executables in your project are expected to be placed in `./common` or `../common`.\n* Tests are expected to end with `_test.cpp` and will be ignored when building `main.cpp`.\n* See the `hello` example in the `examples` directory for the suggested directory structure.\n* For now, *CXX* is only meant to be able to build executables, not libraries.\n* The dependency discovery is reasonably fast, the compilation itself still takes the longest time. Not to speak of the time it can take to discover build flags for some C++ libraries and features manually.\n* For now, the generated `CMakeLists.txt` file is only meant to be used on the system it was generated on, not shipped for many different systems.\n\n## Suggested directory structure\n\nFor a \"Hello, World!\" program that places the text-generation in a `string hello()` function, this is one way to structure the files, for separating the code into easily testable source files:\n\n\n```\n.\n├── hello/main.cpp\n├── hello/include/hello.h\n├── hello/include/test.h\n├── hello/common/hello.cpp\n└── hello/common/hello_test.cpp\n```\n\n#### --- or if you prefer one directory per executable ---\n\n```\n.\n└── hello/hello1/main.cpp\n└── hello/hello2/main.cpp\n└── hello/include/hello.h\n└── hello/include/test.h\n└── hello/common/hello.cpp\n└── hello/common/hello_test.cpp\n```\n\n**main.cpp**\n\n```c++\n#include \u003ciostream\u003e\n#include \"hello.h\"\n\nint main()\n{\n    std::cout \u003c\u003c hello() \u003c\u003c std::endl;\n    return 0;\n}\n```\n\n**hello.h**\n\n```c++\n#pragma once\n\n#include \u003cstring\u003e\n\nstd::string hello();\n```\n\n**hello.cpp**\n\n```c++\n#include \"hello.h\"\n\nusing namespace std::literals;\n\nstd::string hello()\n{\n    return \"Hello, World!\"s;\n}\n```\n\n**hello_test.cpp**\n\n```c++\n#include \"test.h\"\n#include \"hello.h\"\n\nusing namespace std::literals;\n\nvoid hello_test()\n{\n    equal(hello(), \"Hello, World!\"s);\n}\n\nint main()\n{\n    hello_test();\n    return 0;\n}\n```\n\n**test.h**\n\n```c++\n#pragma once\n\n#include \u003ciostream\u003e\n#include \u003ccstdlib\u003e\n\ntemplate\u003ctypename T\u003e\nvoid equal(T a, T b)\n{\n    if (a == b) {\n      std::cout \u003c\u003c \"YES\" \u003c\u003c std::endl;\n    } else {\n      std::cerr \u003c\u003c \"NO\" \u003c\u003c std::endl;\n      exit(EXIT_FAILURE);\n    }\n}\n```\n\n## Requirements\n\n* `scons`\n* `make`\n* `g++` with support for `-std=c++20`.\n* `pkg-config`, for systems where pkg-config is available\n\n#### Optional requirements\n\n* `clang++` with support for `-std=c++20` (build with `cxx clang`).\n* `lldb` or `gdb` for debugging\n* `pkgfile` on Arch Linux, for faster dependency discovery.\n* `apt-file` on Debian/Ubuntu, for faster dependency discovery.\n* `x86_64-w64-mingw32-g++` or `docker`, for cross-compiling executables for 64-bit Windows. The docker service must be up and running for this to work.\n* `wine`, for testing executables compiled for 64-bit Windows (`cxx run`).\n* `valgrind`, for profiling (`cxx valgrind`).\n* `kcachegrind`, for viewing the information produced by *valgrind*.\n* `gprof2dot` and `dot`, for producing a graph from the information produced by valgrind.\n* `vagrant`, for testing *cxx* on other operating systems.\n* `figlet`, for nicer output when running the `tests/build_all.sh` script, for building all the examples.\n* Development packages for `SDL2`, `OpenGL`, `glut`, `glfw`, `sfml`, `GTK+4`, `Qt6` and `Vulkan`, for building and running the examples.\n* `x86_64-w64-mingw32-g++` or `docker` is needed for building the `win64crate` example.\n* `clang-format` for `cxx fmt`.\n\n## C++20 on macOS\n\nFor installing a recent enough version of C++ on macOS, installing gcc 11 with `brew` is one possible approach:\n\n    brew install gcc@11\n\nThe other requirements can be installed with:\n\n    brew install scons make pkg-config\n\n## C++20 on Arch Linux\n\ng++ with support for `-std=c++20` should already be installed.\n\nInstall scons and base-devel, if needed:\n\n    pacman -S scons base-devel --needed\n\n## C++20 on Debian or Ubuntu\n\nYou might need to install GCC 11 from the testing repository, or from a PPA.\n\nInstall build-essential, scons and pkg-config:\n\n    apt install build-essential scons pkg-config\n\n## C++20 on FreeBSD\n\nFreeBSD 11.1 comes with C++17 support, but you may wish to install GCC 11 or later.\n\ngcc11 or later should provide support for C++20.\n\nInstall pkg-conf, scons and gmake:\n\n    pkg install pkgconf scons gmake\n\n## Installation\n\nManual installation with `make` and `sudo`:\n\n`sudo make install`\n\nOn FreeBSD, use `gmake` instead of `make`.\n\nIf possible, install *CXX* with the package manager that comes with your OS/distro.\n\n## Uninstallation\n\n`sudo make uninstall`\n\n## One way of structuring projects\n\n#### Filenames\n\n* All include filenames should contain no spaces or special characters (a-z, A-Z, 0-9) and end with `.h` or `.hpp`.\n* All C++ source filenames should contain no spaces or special characters (a-z, A-Z, 0-9) and end with `.cpp`, `.cc` or `.cxx`.\n* The main source file could be named `main.cpp` or `main.cc`, but it does not have to.\n* Files ending with `_test.*` are special, and will not be used when compiling the main executable(s).\n\n#### Ninja\n\n* Projects that already uses CMake (and need no extra command line arguments when running `cmake`) are also CXX compatible and can be built with CMake + Ninja like this:\n\n    cxx ninja\n\n#### QtCreator\n\nThe generated qmake/QtCreator project files were tested with QtCreator 4.6 on Arch Linux.\n\n## Source code formatting\n\n* `cxx fmt` will format C++20 source code in a single, fixed, formatting style (clang-format \"Webkit\"-style), which is not configurable, on purpose. Using `cxx fmt` is optional.\n\n## Feedback\n\nThe goal is that every executable and project written in C++20 should be able to build with `cxx` on a modern Linux distro, FreeBSD or macOS system (with Homebrew), without any additional configuration.\n\nIf you have a project written in C++ that you think should be able to build with `cxx`, but doesn't, please create an issue and include a link to your repository.\n\n## GNU Parallel\n\nIf running CXX with `parallel`, make sure to use the `--compress` or `--tmpdir` flag to change the location of the temporary SQLite database.\n\nExample build target in a Makefile, for using `parallel` and `cxx`, while disabling warnings:\n\n    build:\n        +CXXFLAGS='$(CXXFLAGS) -w' parallel --compress cxx opt -C ::: subdir1 subdir2 subdir3\n\n`subdir1`, `subdir2` and `subdir3` are just examples of directory names.\n\n## OpenBSD\n\nFor OpenBSD, install g++ 11 and build with `cxx CXX=eg++`.\n\n## GTK and Qt\n\n* Only the latest version of GTK and Qt are supported. Currently, that's GTK+4 and Qt6. Please create an issue or submit a pull request if there are new releases of GTK or Qt.\n* The GTK and Qt examples are currently only tested on Arch Linux.\n\n## Editor Configuration\n\nSyntastic settings for ViM and NeoVim:\n\n    \" If your compiler does not support -std=c++20, it is possible to use -std=c++2a, -std=c++2b or -std=c++17.\n    let g:syntastic_cpp_compiler = 'g++'\n    let g:syntastic_cpp_compiler_options = ' -std=c++20 -pipe -fPIC -fno-plt -fstack-protector-strong -Wall -Wshadow -Wpedantic -Wno-parentheses -Wfatal-errors -Wvla'\n    let g:syntastic_cpp_include_dirs = ['../common', './common', '../include', './include']\n\n    \" Ignore some defines and warnings\n    let g:syntastic_quiet_messages = {\n        \\ \"!level\": \"errors\",\n        \\ \"regex\":  [ 'RESOURCEDIR', 'RESDIR', 'DATADIR', 'IMGDIR', 'SHAREDIR', 'SHADERDIR', 'expected .*).* before string constant' ] }\n\n## General info\n\n* Version: 3.3.3\n* License: BSD-3\n* Author: Alexander F. Rødseth \u0026lt;xyproto@archlinux.org\u0026gt;\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxyproto%2Fcxx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxyproto%2Fcxx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxyproto%2Fcxx/lists"}