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
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

1
compile_commands.json Symbolic link
View File

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

View File

@ -20,7 +20,7 @@
in
{
packages = {
release = pkgs.stdenv.mkDerivation {
app = pkgs.stdenv.mkDerivation {
pname = "bootstrap";
src = ./.;
version = "0.1.3";
@ -39,7 +39,7 @@
if [ -z "$BOOTSTRAP_ROOT_DIR" ]; then
export BOOTSTRAP_ROOT_DIR="${./specs}"
fi
exec ${self.packages.${system}.release}/bootstrap "$@"
exec ${self.packages.${system}.app}/bin/bootstrap "$@"
'';
};
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
# happen but a good habit to establish nonetheless.
function cleanup {
rm -r "/tmp/bs.clang/$(basename "$BUILD")"
yes | rm -r "/tmp/bs.clang/$(basename "$BUILD")"
}
trap cleanup EXIT
@ -47,6 +47,20 @@ find "$BUILD" -type f -execdir chmod 644 {} +
find "$BUILD" -type d -execdir chmod 755 {} +
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
# ============================================================

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

View File

@ -1,7 +1,33 @@
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
```
## 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
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
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
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)
must be generated. [CMake](https://cmake.org/) (version 3.27.7) is included in
this flake with `CMAKE_EXPORT_COMPILE_COMMANDS` already set from the
`CMakeLists.txt` file.
must be generated. The `CMakeLists.txt` file already enables this in the Debug
configuration type. A top-level `compile_commands.json` symbolic link already
exists and points to this generated database.
## Documentation
@ -29,12 +47,22 @@ running:
$ 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 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.
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
$ 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";
};
outputs = { nixpkgs, flake-utils, ... }:
outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
@ -25,6 +25,25 @@
'';
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 {
# https://nixos.wiki/wiki/Using_Clang_instead_of_GCC
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(); }