Migrate clang project to fuller CMake configuration.

pull/1/head
Joshua Potter 2023-12-21 16:54:49 -05:00
parent 52e6f971e8
commit 5311fc0cef
16 changed files with 137 additions and 17 deletions

1
.gitignore vendored
View File

@ -22,6 +22,5 @@ Testing
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt
compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
_deps _deps

1
compile_commands.json Symbolic link
View File

@ -0,0 +1 @@
build/Debug/compile_commands.json

View File

@ -20,7 +20,7 @@
in in
{ {
packages = { packages = {
release = pkgs.stdenv.mkDerivation { app = pkgs.stdenv.mkDerivation {
pname = "bootstrap"; pname = "bootstrap";
src = ./.; src = ./.;
version = "0.1.3"; version = "0.1.3";
@ -39,7 +39,7 @@
if [ -z "$BOOTSTRAP_ROOT_DIR" ]; then if [ -z "$BOOTSTRAP_ROOT_DIR" ]; then
export BOOTSTRAP_ROOT_DIR="${./specs}" export BOOTSTRAP_ROOT_DIR="${./specs}"
fi fi
exec ${self.packages.${system}.release}/bootstrap "$@" exec ${self.packages.${system}.app}/bin/bootstrap "$@"
''; '';
}; };
devShells.default = pkgs.mkShell.override { devShells.default = pkgs.mkShell.override {

View File

@ -30,7 +30,7 @@ fi
# to ensure we never evaluate to root (i.e. `/`). That should never actually # to ensure we never evaluate to root (i.e. `/`). That should never actually
# happen but a good habit to establish nonetheless. # happen but a good habit to establish nonetheless.
function cleanup { function cleanup {
rm -r "/tmp/bs.clang/$(basename "$BUILD")" yes | rm -r "/tmp/bs.clang/$(basename "$BUILD")"
} }
trap cleanup EXIT trap cleanup EXIT
@ -47,6 +47,20 @@ find "$BUILD" -type f -execdir chmod 644 {} +
find "$BUILD" -type d -execdir chmod 755 {} + find "$BUILD" -type d -execdir chmod 755 {} +
chmod 755 "$BUILD"/.githooks/pre-commit chmod 755 "$BUILD"/.githooks/pre-commit
# Create new subdirectories for out-of-source builds. Each should be initialized
# with `CMAKE_BUILD_TYPE` set appropriately during configuration, e.g.
# `cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug ../..`
mkdir -p "$BUILD"/build/{Debug,Release}
# ============================================================
# REWRITES
# ============================================================
for file in flake.nix {,src/,test/}CMakeLists.txt
do
sed -i "s/<NAME>/$NAME/g" "$BUILD/$file"
done
# ============================================================ # ============================================================
# EPILOGUE # EPILOGUE
# ============================================================ # ============================================================

6
specs/clang/spec.json Normal file
View File

@ -0,0 +1,6 @@
{
"name": {
"type": "line",
"prompt": "Name> "
}
}

View File

@ -5,7 +5,7 @@
/.direnv/ /.direnv/
# The directory containing all build outputs. # The directory containing all build outputs.
/dist/ /build/
# The directory generated by `Doxygen`. # The directory generated by `Doxygen`.
/docs/ /docs/
@ -25,6 +25,5 @@ Testing
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt
compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
_deps _deps

View File

@ -1,7 +1,33 @@
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.15)
project("<NAME>" VERSION 0.1.0)
project(App VERSION 0.1.0) # The primary executable.
add_executable("<NAME>" main.c)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Include the cmake commands found in `src`. This subdirectory is responsible
# for linking the other project source files to our executable.
add_subdirectory(src)
add_executable(a.out main.c) # An example on linking additional libraries. In this case, links `math`.
target_link_libraries("<NAME>" PUBLIC m)
# Location of different headers to include when compiling the executable.
target_include_directories("<NAME>" PUBLIC include)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set_target_properties(
"<NAME>" PROPERTIES
# The top-level `compile_commands.json` is a symbolic link to this file.
EXPORT_COMPILE_COMMANDS ON
# Enable so that tests can link against the primary executable.
ENABLE_EXPORTS ON
)
# Turns on testing. This must be done at the root `CMakeLists.txt` file. If
# looking for additional testing configuration, consider using
# `include(CTest)` instead.
enable_testing()
# Add test files to our cmake configuration.
add_subdirectory(test)
endif()

View File

@ -8,17 +8,35 @@ can be used to launch a dev shell upon entering this directory (refer to
$ nix develop $ nix develop
``` ```
## Building
We use [CMake](https://cmake.org/) (version 3.27.7) to build the project. When
first starting the project, we recommend running the following commands:
```bash
$ mkdir -p build/{Debug,Release}
$ (cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug ../..)
$ (cd build/Release && cmake -DCMAKE_BUILD_TYPE=Release ../..)
```
This will create a CMake cache file in each subdirectory with the build types
set. Now you can build a `Debug` or `Release` variant by navigating to the
corresponding subdirectory and running:
```bash
$ cmake --build .
```
## Language Server ## Language Server
The [clangd](https://clangd.llvm.org/) LSP (version 14.0.6) is included in this The [clangd](https://clangd.llvm.org/) LSP (version 14.0.6) is included in this
flake. The [codelldb](https://github.com/vadimcn/codelldb) VSCode plugin is also flake. The [codelldb](https://github.com/vadimcn/codelldb) VSCode plugin is also
included to interface with the LSP. Note this plugin, despite its name, is included to interface with the LSP. Note this plugin, despite its name, is
compatible with other editors (e.g. neovim). To configure, refer to your compatible with other editors (e.g. neovim). To configure, refer to your
editor's documentation. To use the LSP across files, a editor's documentation.
To use the LSP across files, a
[compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
must be generated. [CMake](https://cmake.org/) (version 3.27.7) is included in must be generated. The `CMakeLists.txt` file already enables this in the Debug
this flake with `CMAKE_EXPORT_COMPILE_COMMANDS` already set from the configuration type. A top-level `compile_commands.json` symbolic link already
`CMakeLists.txt` file. exists and points to this generated database.
## Documentation ## Documentation
@ -29,12 +47,22 @@ running:
$ doxygen $ doxygen
``` ```
## Testing
We use [CTest](https://cmake.org/cmake/help/latest/module/CTest.html) (version
3.27.7) for unit testing. To run the tests, navigate to `build/Debug` and type
the following:
```bash
$ cmake --build .
$ make test
```
## Formatting ## Formatting
Formatting depends on the [clang-format](https://clang.llvm.org/docs/ClangFormat.html) Formatting depends on the [clang-format](https://clang.llvm.org/docs/ClangFormat.html)
(version 14.0.6) tool. Refer to `.clang-format` for default formatting options. (version 14.0.6) tool. Refer to `.clang-format` for default formatting options.
A `pre-commit` hook is included in `.githooks` that can be used to format all A `pre-commit` hook is included in `.githooks` that can be used to format all
`*.c` and `*.h` files prior to commit. Install via: `*.c(pp)?` and `*.h(pp)?` files prior to commit. Install via:
```bash ```bash
$ git config --local core.hooksPath .githooks/ $ git config --local core.hooksPath .githooks/
``` ```

View File

@ -0,0 +1 @@
build/Debug/compile_commands.json

View File

@ -15,7 +15,7 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
}; };
outputs = { nixpkgs, flake-utils, ... }: outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system: flake-utils.lib.eachDefaultSystem (system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
@ -25,6 +25,25 @@
''; '';
in in
{ {
packages = {
app = pkgs.stdenv.mkDerivation {
pname = "<NAME>";
src = ./.;
version = "0.1.0";
nativeBuildInputs = with pkgs; [ cmake ];
buildPhase = ''
cmake -DCMAKE_BUILD_TYPE=Release .
cmake --build .
'';
installPhase = ''
mkdir -p $out/bin
cp ./"<NAME>" $out/bin
'';
};
default = self.packages.${system}.app;
};
devShells.default = pkgs.mkShell.override { devShells.default = pkgs.mkShell.override {
# https://nixos.wiki/wiki/Using_Clang_instead_of_GCC # https://nixos.wiki/wiki/Using_Clang_instead_of_GCC
stdenv = pkgs.clangStdenv; stdenv = pkgs.clangStdenv;

View File

@ -0,0 +1,6 @@
#ifndef _HELLO_H
#define _HELLO_H
int hello_world();
#endif /* _HELLO_H */

View File

@ -1,3 +1,3 @@
#include <stdlib.h> #include "hello.h"
int main(int argc, char *argv[argc + 1]) { return EXIT_SUCCESS; } int main(int argc, char *argv[argc + 1]) { return hello_world(); }

View File

@ -0,0 +1,5 @@
target_sources(
"<NAME>" PUBLIC
hello.c
)

View File

@ -0,0 +1,8 @@
#include "hello.h"
#include <stdio.h>
int hello_world() {
printf("Hello, world!\n");
return 0;
}

View File

@ -0,0 +1,5 @@
add_executable(test-hello test_hello.c)
target_link_libraries(test-hello PRIVATE "<NAME>")
target_include_directories(test-hello PRIVATE "<NAME>")
add_test(NAME hello COMMAND ./test-hello)

View File

@ -0,0 +1,3 @@
#include "hello.h"
int main(int argc, char **argv) { return hello_world(); }