diff --git a/.clangd b/.clangd index 2936bda..b38a9a7 100644 --- a/.clangd +++ b/.clangd @@ -3,7 +3,7 @@ # Copyright (c) 2023 Johnathan C Maudlin --- CompileFlags: - CompilationDatabase: build + CompilationDatabase: builddir Diagnostics: UnusedIncludes: Strict diff --git a/.editorconfig b/.editorconfig index 259ecdf..c80fc4b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -29,7 +29,6 @@ tab_width = 2 indent_size = 2 tab_width = 2 -[Makefile] -indent_size = 4 -indent_style = "tab" -tab_width = 4 +[meson.build] +indent_size = 2 +tab_width = 2 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 68a1248..7656f5f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,9 +11,8 @@ on: - .clang-tidy - .clangd - .github/workflows/lint.yml - - .prettierrc.yml - - include/**/*.h - meson.build + - include/**/*.h - src/**/*.c - src/**/meson.build push: @@ -22,9 +21,8 @@ on: - .clang-tidy - .clangd - .github/workflows/lint.yml - - .prettierrc.yml - - include/**/*.h - meson.build + - include/**/*.h - src/**/*.c - src/**/meson.build workflow_dispatch: @@ -34,41 +32,33 @@ jobs: strategy: fail-fast: false matrix: - linter: - - clang-format - - clang-tidy + linter: [clang-format, clang-tidy] os: - name: ubuntu-latest - deps: clang{,-{format,tidy}} cmake git libasan5 libubsan1 lld ninja-build + deps: > + clang{,-{format,tidy}} git lld meson ninja-build + libgc-dev libreadline-dev libasan5 libubsan1 name: ${{ matrix.linter }} (${{ matrix.os.name }}) runs-on: ${{ matrix.os.name }} steps: - uses: actions/checkout@v4 - with: { submodules: true } - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y --no-install-{recommends,suggests} ${{ matrix.os.deps }} - - name: Setup build cache - uses: actions/cache@v3 - id: build - with: - key: ${{ hashFiles('**/CMakeLists.txt', 'src/*.c', 'include/**/*.h') }} - path: build/ - - - name: Build Ploy (Debug) - env: { CC: clang, CXX: clang++, LD: lld } + - name: Build Ploy + env: { CC: clang, CC_LD: lld, NINJA: ninja } run: | - [ ! -e build ] && mkdir build - cmake -G Ninja -B build/ -S ./ \ - -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" - ninja -C build/ + meson setup builddir -Db_sanitize=address,undefined -Dbuildtype=debugoptimized + ninja -C builddir + + - name: Test Ploy + run: ninja -C builddir test # TODO(jcmdln): Only in actions, clang-tidy warns about suppressed warnings - name: Run ${{ matrix.linter }} - run: | - ninja -C build ${{ matrix.linter }} + run: ninja -C builddir ${{ matrix.linter }} diff --git a/.gitignore b/.gitignore index e504ff6..723e1af 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ !.gitignore !.prettierrc.yml !LICENSE -!CMakeLists.txt +!meson.build !Makefile !README.md diff --git a/.vscode/cmake-kits.json b/.vscode/cmake-kits.json deleted file mode 100644 index 44fc356..0000000 --- a/.vscode/cmake-kits.json +++ /dev/null @@ -1,39 +0,0 @@ -[ - { - "name": "Linux-Clang", - "compilers": { - "CC": "clang", - "CC_LD": "lld", - "CXX": "clang++", - "CXX_LD": "lld", - "LD": "lld" - } - }, - { - "name": "Linux-Clang-Mold", - "compilers": { - "CC": "clang", - "CC_LD": "mold", - "CXX": "clang++", - "CXX_LD": "mold", - "LD": "mold" - } - }, - { - "name": "Linux-GCC", - "compilers": { - "CC": "/usr/bin/gcc", - "CXX": "/usr/bin/g++" - } - }, - { - "name": "Linux-GCC-Mold", - "compilers": { - "CC": "gcc", - "CC_LD": "mold", - "CXX": "g++", - "CXX_LD": "mold", - "LD": "mold" - } - } -] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 62bbeca..9500a21 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,6 +5,7 @@ "llvm-vs-code-extensions.vscode-clangd", "redhat.vscode-yaml", "vadimcn.vscode-lldb", - "ms-vscode.cmake-tools" + "ms-vscode.cmake-tools", + "mesonbuild.mesonbuild" ] } diff --git a/.vscode/launch.json b/.vscode/launch.json index 6e5dfe1..8e60a7c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "type": "lldb", "request": "launch", "name": "Debug Ploy", - "program": "${workspaceFolder}/build/ploy", + "program": "${workspaceFolder}/builddir/ploy", "args": [], "cwd": "${workspaceFolder}" } diff --git a/.vscode/settings.json b/.vscode/settings.json index 682e0a4..3fff198 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,6 +27,14 @@ "**/builddir/**": true }, + // mesonbuild: Don't pester about or download a random binary + "mesonbuild.downloadLanguageServer": false, + "mesonbuild.languageServer": null, + + "mesonbuild.formatting.enabled": false, + "mesonbuild.linter.muon.enabled": true, + "mesonbuild.muonPath": "muon", + // Associate YAML schemas with targets "yaml.schemas": { "https://json.schemastore.org/github-workflow.json": [ @@ -45,5 +53,8 @@ }, "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[meson]": { + "editor.defaultFormatter": "mesonbuild.mesonbuild" } } diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index a55364c..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,98 +0,0 @@ -# SPDX-License-Identifier: ISC -# -# Copyright (c) 2023 Johnathan C Maudlin - -cmake_minimum_required(VERSION 3.13) -project(Ploy LANGUAGES C VERSION 0.0.1) - -add_executable(ploy - src/main.c - src/core.c - src/evaluator.c - src/math.c - src/printer.c - src/reader.c - src/type.c -) - -target_include_directories(ploy PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") - -# -# Compilation -# - -target_compile_features(ploy PRIVATE c_std_11) - -target_compile_options(ploy PRIVATE - -DPLOY_VERSION=\"${CMAKE_PROJECT_VERSION}\" - -fshort-wchar -fstrict-aliasing -funsigned-char - -Wall -Wextra -pedantic - -Werror=cast-qual - -Werror=conversion - -Werror=implicit-int - -Werror=strict-prototypes - -Werror=switch - -Werror=vla - -Werror=write-strings -) - -option(PLOY_LTO "Build ploy with link-time optimization" OFF) -if (PLOY_LTO) - target_compile_options(ploy PRIVATE -flto) - target_link_options(ploy PRIVATE -flto) -endif() - -option(PLOY_USE_ASAN "Build ploy with AddressSanitizer" OFF) -if (PLOY_USE_ASAN) - target_compile_options(ploy PRIVATE -fsanitize=address,undefined) - target_link_options(ploy PRIVATE -fsanitize=address,undefined) -endif() - -option(PLOY_USE_TSAN "Build ploy with ThreadSanitizer" OFF) -if (PLOY_USE_TSAN) - target_compile_options(ploy PRIVATE -fsanitize=thread,undefined) - target_link_options(ploy PRIVATE -fsanitize=thread,undefined) -endif() - -# -# Dependencies -# - -find_package(PkgConfig) -if (PKG_CONFIG_FOUND) - pkg_check_modules(bdwgc REQUIRED IMPORTED_TARGET bdw-gc>=8) - pkg_check_modules(readline REQUIRED IMPORTED_TARGET readline>=8) - - target_link_libraries(ploy PUBLIC - PkgConfig::bdwgc - PkgConfig::readline - ) -endif() - -# -# Ploy -# - -# -DPLOY_BIN_DIR -# -DPLOY_LIB_DIR -# -DPLOY_VERSION - -# -# Lints -# - -add_custom_target(clang-format -COMMAND clang-format --dry-run --verbose --Werror - "${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c" -) - -add_custom_target(clang-tidy -COMMAND clang-tidy -p "${CMAKE_CURRENT_SOURCE_DIR}/build" - "${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.h" - "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c" -) - -# -# Tests -# diff --git a/Makefile b/Makefile deleted file mode 100644 index dd1a23d..0000000 --- a/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-License-Identifier: ISC -# -# Copyright (c) 2023 Johnathan C Maudlin -.POSIX: - -VERSION = 0.0.1 - -CC = cc -CFLAGS = -O2 -std=c11 \ - -fshort-wchar -fstrict-aliasing -funsigned-char \ - -Wall -Wextra -pedantic \ - -Werror=cast-qual \ - -Werror=conversion \ - -Werror=implicit-int \ - -Werror=strict-prototypes \ - -Werror=switch \ - -Werror=vla \ - -Werror=write-strings -LDFLAGS = -D_DEFAULT_SOURCE -DPLOY_VERSION=\"$(VERSION)\" \ - -Iinclude/ -lgc -lm -lreadline -pthread -PREFIX = /usr/local -SOURCES = \ - src/main.c \ - src/core.c \ - src/evaluator.c \ - src/math.c \ - src/printer.c \ - src/reader.c \ - src/type.c - -all: release - -clean: - rm -f ploy - -debug: $(SOURCES) - $(CC) -g -Werror $(CFLAGS) -o ploy $(SOURCES) $(LDFLAGS) -asan: $(SOURCES) - $(CC) -g -Werror -fsanitize=address,undefined $(CFLAGS) -o ploy $(SOURCES) $(LDFLAGS) -tsan: $(SOURCES) - $(CC) -g -Werror -fsanitize=thread $(CFLAGS) -o ploy $(SOURCES) $(LDFLAGS) -release: $(SOURCES) - $(CC) $(CFLAGS) -o ploy $(SOURCES) $(LDFLAGS) - -# install: -# -# uninstall: diff --git a/README.md b/README.md index 6debd7e..5ca4faf 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,17 @@ Ploy is a (work-in-progress) lisp-like language for my own fun and learning. Building Ploy requires the following: - A [c11] compiler -- [CMake] and [Ninja] +- [Meson] (or [Muon]) and [Ninja] (or [Samurai]) - [bdwgc] -- [linenoise] +- [GNU Readline][readline] -[bdwgc]: http://www.hboehm.info/gc/ +[bdwgc]: https://github.com/ivmai/bdwgc [c11]: https://en.wikipedia.org/wiki/C11_(C_standard_revision) -[cmake]: https://cmake.org/ +[meson]: https://mesonbuild.com/ +[muon]: https://muon.build/ [ninja]: https://ninja-build.org/ -[linenoise]: https://github.com/antirez/linenoise +[readline]: https://git.savannah.gnu.org/cgit/readline.git +[samurai]: https://github.com/michaelforney/samurai # Using @@ -19,48 +21,37 @@ This section describes various ways of using Ploy. ## Build -This section describes building Ploy. - -```sh -git clone --origin upstream --recurse-submodules https://github.com/jcmdln/ploy -cd ploy -``` - ### Release -This section describes performing a release build of Ploy. - ```sh # Fedora -sudo dnf install -y cmake git ninja +sudo dnf install -y gc-devel meson ninja-build pkgconf readline-devel ``` ```sh -mkdir build -cd build -cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -ninja +meson setup builddir +ninja -C builddir ``` ### Debug -This section describes performing a debug build of Ploy. - -If you don't want [ASan]/[UBSan], use `-DCMAKE_BUILD_TYPE=RelWithDebInfo`. - -[ASan]: https://clang.llvm.org/docs/AddressSanitizer.html -[UBSan]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html +When performing a debug build, install additional sanitizers and manually set +the specified options with Meson: ```sh -# Fedora -sudo dnf install -y libasan libubsan +sudo dnf install -y clang-tools-extra libasan libubsan +meson setup builddir -Db_sanitize=address,undefined -Dbuildtype=debugoptimized +ninja -C builddir ``` +When setting up the meson builddir, you may want to consider setting additional +environment variables to specify an alternate compiler, linker, meson or ninja +implementation: + ```sh -mkdir build -cd build -cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug -ninja +CC="clang" CC_LD="mold" NINJA="samu" \ +muon setup -Db_sanitize=address,undefined -Dbuildtype=debugoptimized builddir +samu -C builddir ``` ## Lint @@ -77,7 +68,7 @@ sudo dnf install -y clang-tools-extra See [.clang-format](./.clang-format) for the settings: ```sh -ninja -C build clang-format +ninja -C builddir clang-format ``` ### clang-tidy @@ -85,19 +76,19 @@ ninja -C build clang-format See [.clang-tidy](./.clang-tidy) for the settings: ```sh -ninja -C build clang-tidy +ninja -C builddir clang-tidy ``` ## Test -This section describes how to run tests. +```sh +ninja -C builddir test +``` ## Run -This section describes running Ploy - ```sh -$ ./build/ploy -h +$ ./builddir/ploy -h usage: ploy [-h] [-e EXPR | -f FILE] -e Evaluate an expression @@ -107,18 +98,14 @@ usage: ploy [-h] [-e EXPR | -f FILE] ## Install -This section describes installing Ploy. - ```sh -ninja -C build install +ninja -C builddir install ``` ## Uninstall -This section describes uninstalling Ploy. - ```sh -ninja -C build uninstall +ninja -C builddir uninstall ``` # Special Thanks diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..0b2d285 --- /dev/null +++ b/meson.build @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2023 Johnathan C Maudlin + +project('ploy', 'c', + default_options: [ + 'buildtype=release', + 'c_std=c11', + 'warning_level=3', + 'werror=false', + ], + license: 'ISC', + meson_version: '>=0.46', + version: '0.0.0', +) + +# +# Compilation +# + +compiler = meson.get_compiler('c', native: true) +add_project_arguments(compiler.get_supported_arguments([ + '-fshort-wchar', + '-fstrict-aliasing', + '-funsigned-char', + '-Werror=cast-qual', + '-Werror=implicit-int', + '-Werror=restrict', + '-Werror=strict-prototypes', + '-Werror=switch', + '-Werror=vla', + '-Werror=write-strings', +]), language: 'c') + +# +# Dependencies +# + +bdwgc = dependency('bdw-gc', required: true) +readline = dependency('readline', required: true) + +# +# Executables +# + +ploy_include = include_directories('include') +ploy_includes = files( + 'include/ploy/core.h', + 'include/ploy/evaluator.h', + 'include/ploy/math.h', + 'include/ploy/printer.h', + 'include/ploy/reader.h', + 'include/ploy/type.h', +) + +ploy_main = files('src/main.c') +ploy_src = files( + 'src/core.c', + 'src/evaluator.c', + 'src/math.c', + 'src/printer.c', + 'src/reader.c', + 'src/type.c', +) + +executable('ploy', + dependencies: [bdwgc, readline], + include_directories: ploy_include, + install: true, + sources: [ploy_src, ploy_main], +) + +# +# Tests +# + +ploy_tests = [] +subdir('test') + +# +# Lints +# + +run_target('clang-format', command: [ + 'clang-format', '--dry-run', '--verbose', '--Werror', + ploy_includes, ploy_src, ploy_main, ploy_tests]) + +run_target('clang-tidy', command: [ + 'clang-tidy', '--quiet', '-p', 'builddir/', + ploy_includes, ploy_src, ploy_main, ploy_tests]) diff --git a/test/core/meson.build b/test/core/meson.build new file mode 100644 index 0000000..4327663 --- /dev/null +++ b/test/core/meson.build @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2023 Johnathan C Maudlin + +car = files('car.c') +cdr = files('cdr.c') +cons = files('cons.c') +read = files('read.c') +reverse = files('reverse.c') + +ploy_tests += car + cdr + cons + read + reverse + +test('core_car', executable('car', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, car] +)) + +test('core_cdr', executable('cdr', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, cdr] +)) + +test('core_cons', executable('cons', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, cons] +)) + +test('core_read', executable('read', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, read] +)) + +test('core_reverse', executable('reverse', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, reverse] +)) diff --git a/test/math/meson.build b/test/math/meson.build new file mode 100644 index 0000000..7e39b91 --- /dev/null +++ b/test/math/meson.build @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2023 Johnathan C Maudlin + +add = files('add.c') +divide = files('divide.c') +multiply = files('multiply.c') +subtract = files('subtract.c') + +ploy_tests += add + divide + multiply + subtract + +test('math_add', executable('add', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, add] +)) + +test('math_divide', executable('divide', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, divide] +)) + +test('math_multiply', executable('multiply', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, multiply] +)) + +test('math_subtract', executable('subtract', + build_by_default: false, + dependencies: [bdwgc], + include_directories: ploy_include, + sources: [ploy_src, subtract] +)) diff --git a/test/CMakeLists.txt b/test/meson.build similarity index 75% rename from test/CMakeLists.txt rename to test/meson.build index 4ad2d22..fd8b263 100644 --- a/test/CMakeLists.txt +++ b/test/meson.build @@ -1,3 +1,6 @@ # SPDX-License-Identifier: ISC # # Copyright (c) 2023 Johnathan C Maudlin + +subdir('core') +subdir('math')