Compare commits

...

69 Commits
v0.1 ... v0.9

Author SHA1 Message Date
Lars Melchior
f57476ee43 Update README.md 2019-05-17 14:50:27 +02:00
Lars Melchior
db4f2bf7bb Update README.md 2019-05-17 14:47:35 +02:00
Lars Melchior
8d39e34ff2 v0.9 (#46)
* always get properties

* update examples

* update travis

* add doctest example

* update example runner
2019-05-17 14:46:54 +02:00
Lars Melchior
c2a413300e Update README.md 2019-05-11 15:44:22 +02:00
Lars Melchior
5177860756 Update README.md 2019-05-11 15:12:06 +02:00
Lars Melchior
5dad9d4e9d update examples (#45) 2019-05-10 16:20:53 +02:00
Lars Melchior
539974785e Update README.md 2019-05-10 16:03:46 +02:00
Lars Melchior
e4a0cb4980 Update README.md 2019-05-10 13:10:48 +02:00
Lars Melchior
a8ccc42f43 Update README.md 2019-05-10 12:03:09 +02:00
Lars Melchior
f92ed18514 Update README.md 2019-05-10 09:56:57 +02:00
Lars Melchior
153c196c18 Update README.md 2019-05-10 09:56:34 +02:00
Lars Melchior
d91befd7ce Update README.md 2019-05-10 09:55:48 +02:00
Lars Melchior
978c101c7e Update README.md 2019-05-09 13:50:10 +02:00
Lars Melchior
8da680df9b Update README.md 2019-05-09 13:45:44 +02:00
Lars Melchior
6943b38afb Update README.md 2019-05-09 13:36:23 +02:00
Lars Melchior
cf042cf1ac Update README.md 2019-05-09 13:31:18 +02:00
Lars Melchior
bebea37c4a Update CPM.cmake 2019-05-09 13:29:12 +02:00
Lars Melchior
137bda299d Update CPM.cmake (#44)
* Update CPM.cmake

* Update CPM.cmake
2019-05-08 21:36:51 +02:00
Lars Melchior
4d557d128f Update README.md 2019-05-06 10:21:58 +02:00
Lars Melchior
9021499c52 Update CPM.cmake 2019-05-05 11:47:28 +02:00
Lars Melchior
9b97b64da2 Correct version output 2019-05-04 10:39:39 +02:00
Lars Melchior
df752ed5d3 Update CPM.cmake 2019-05-04 10:32:20 +02:00
Lars Melchior
f00f5517a6 Update CPM.cmake (#43)
- Increase Version to 0.8
- Add version check
- Add DOWNLOAD_ONLY option
2019-05-04 10:23:02 +02:00
Lars Melchior
a97b32824e bugfix (#42) 2019-04-28 12:17:30 +02:00
Lars Melchior
e558d795f9 Update CPM.cmake (#41) 2019-04-26 15:44:36 +02:00
Lars Melchior
76748fe542 remove Codacy badge (does not support CMake) (#40) 2019-04-24 13:10:18 +02:00
Lars Melchior
e453671327 Update README.md (#39)
* Update README.md

* Update README.md
2019-04-24 12:47:15 +02:00
Lars Melchior
5192f713d2 Default to remote packages (#38)
* Update CPM.cmake

* Update CPM.cmake

* Update README.md
2019-04-22 20:01:41 +02:00
Lars Melchior
282b98423a Update README.md (#37) 2019-04-22 19:22:23 +02:00
Lars Melchior
2ff0f5f58f Update README.md (#36) 2019-04-20 18:20:01 +02:00
Lars Melchior
9343f7c69a Update README.md (#35) 2019-04-20 12:33:24 +02:00
Lars Melchior
044edb1fd2 add origin comment (#34)
* Update CPM.cmake

* Update CPM.cmake

* add licence to script

* Update CPM.cmake

* Update CPM.cmake
2019-04-18 14:21:45 +02:00
Lars Melchior
07a4d626a1 Remove debug log (#33) 2019-04-18 13:54:43 +02:00
Lars Melchior
0d529f73cd use set_target_properties (#32) 2019-04-18 12:47:22 +02:00
Lars Melchior
96dba3b03c Update README.md (#31) 2019-04-18 12:43:54 +02:00
Lars Melchior
ba256b71c1 Update README.md (#30)
* Update README.md

* Update README.md
2019-04-18 12:35:17 +02:00
Lars Melchior
b3a875e2dd use CPM_LOCAL_PACKAGES_ONLY again (#29) 2019-04-17 22:05:59 +02:00
Lars Melchior
a582911527 Update README.md (#28) 2019-04-17 15:35:00 +02:00
Lars Melchior
0a07f53d6d Update README.md (#27) 2019-04-17 15:24:29 +02:00
Lars Melchior
b81a29b598 Update README.md (#26)
* Update README.md

* Update README.md

* Update README.md

* Update README.md
2019-04-17 15:10:48 +02:00
Lars Melchior
0adcd87add Update README.md (#25)
* Update README.md

* Update README.md

* Update README.md
2019-04-17 13:58:29 +02:00
Lars Melchior
95634c30fd only download if no options are provided (#24) 2019-04-17 13:36:08 +02:00
Lars Melchior
bf205f77b4 Update README.md (#23) 2019-04-17 13:25:48 +02:00
Lars Melchior
610448d275 Update README.md (#22) 2019-04-17 13:11:16 +02:00
Lars Melchior
dd63d9fcdb Dev (#21)
* better debug output

* update example

* update readme
2019-04-17 13:01:56 +02:00
Lars Melchior
f8899a5912 Update README.md (#19)
* Update README.md

* Update README.md

* Update README.md
2019-04-17 12:52:42 +02:00
Lars Melchior
48b84b8cdf rename examples test.cpp -> main.cpp (#20) 2019-04-16 19:57:05 +02:00
Lars Melchior
d3d8a6ab4f rename tests -> examples (#18) 2019-04-15 17:54:53 +02:00
Lars Melchior
923265e7ae Update README.md (#17) 2019-04-15 14:42:17 +02:00
Lars Melchior
f2ad294ef3 only use add_package when VERSION is present (#16) 2019-04-15 14:22:43 +02:00
Lars Melchior
3e65078ce7 Update README.md (#15)
* Update README.md

* Update README.md
2019-04-15 14:06:21 +02:00
Lars Melchior
946019a336 update LarsParser in examples and Readme (#14) 2019-04-14 15:33:57 +02:00
Lars Melchior
2d95c66fa4 add package options (#13)
* add package options

* update tests

* update Glue package
2019-04-14 14:49:35 +02:00
Lars Melchior
77a118d3ce Update test.cpp (#12) 2019-04-14 11:29:07 +02:00
Lars Melchior
4dee712eef Update README.md (#11) 2019-04-11 11:35:59 +02:00
Lars Melchior
3c0d201c76 return when package has been added before (#10) 2019-04-11 11:21:04 +02:00
Lars Melchior
4c22b73ebd Use FetchContent (#9)
* remove CPM_RESET in favor of CPM_OFFLINE

* Use FetchContent

* update travis

* update travis

* update travis

* update travis

* update travis
2019-04-11 10:13:28 +02:00
Lars Melchior
50aa889be8 Update README.md (#7)
* Update README.md

* Update README.md (#8)
2019-04-10 17:54:43 +02:00
Lars Melchior
e4bbd6e215 remove CPM_RESET in favor of CPM_OFFLINE (#6)
* remove CPM_RESET in favor of CPM_OFFLINE

* Update README.md (#5)

* Update README.md

* Update README.md

* Update README.md
2019-04-10 16:43:57 +02:00
Lars Melchior
e368fce6c3 Add CPM_RESET (#4)
* added CPM_RESET option

* update readme

* Update README.md
2019-04-09 20:01:27 +02:00
Lars Melchior
f8e571e416 Merge pull request #3 from TheLartians/dev
update parser version
2019-04-09 18:04:44 +02:00
Lars Melchior
e565e35397 Merge branch 'master' into dev 2019-04-09 17:30:48 +02:00
Lars Melchior
702f413801 update Parser lib 2019-04-09 17:30:18 +02:00
Lars Melchior
03b2dd0cb9 Merge pull request #2 from TheLartians/dev
update readme
2019-04-09 17:19:53 +02:00
Lars Melchior
4badcddc5d update readme 2019-04-09 17:10:44 +02:00
Lars Melchior
72371bcc8b Merge pull request #1 from TheLartians/dev
remove test log
2019-04-09 17:07:51 +02:00
Lars Melchior
0798050d6d Merge branch 'master' into dev 2019-04-09 17:00:22 +02:00
Lars Melchior
ffa310199a remove test log 2019-04-09 16:59:49 +02:00
Lars Melchior
cd3cdfd197 Update README.md 2019-04-09 16:49:19 +02:00
21 changed files with 654 additions and 404 deletions

View File

@@ -1,11 +1,14 @@
language: cpp
sudo: require
dist: xenial
common_sources: &all_sources
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty
- llvm-toolchain-trusty-6.0
python:
- 3.7
matrix:
include:
@@ -34,12 +37,12 @@ before_install:
# Update compilers
- eval "${MATRIX_EVAL}"
- echo "CC=$CC CXX=$CXX"
# Install a supported cmake version (>= 3.14)
- wget -O cmake.sh https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh
- sudo sh cmake.sh --skip-license --exclude-subdir --prefix=/usr/local
- export PATH=/usr/local/bin:$PATH
- cmake --version
script:
- cmake -Htests/simple -Bbuild/simple
- cmake --build build/simple
- CTEST_OUTPUT_ON_FAILURE=1 cmake --build build/simple --target test
- cmake -Htests/complex -Bbuild/complex
- cmake --build build/complex
- CTEST_OUTPUT_ON_FAILURE=1 cmake --build build/complex --target test
- python3 examples/run_all.py

139
README.md
View File

@@ -2,34 +2,145 @@
# CPM
CPM is a very simple package manager written in Cmake based on the amazing [DownloadProject](https://github.com/Crascit/DownloadProject) script. It is extremely easy to use and drastically simplifies the inclusion of other Cmake-based projects from github.
CPM is a simple dependency manager written in CMake built on top of CMake's built-in [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module.
# Usage
## Supported projects
To add a new dependency to your project simply add the Projects target name, the git URL and the version. If the git tag for this version does not match the pattern `v$VERSION`, then the exact branch or tag can be specified with the `GIT_TAG` argument.
Any project that you can add via `add_subdirectory` should already work with CPM.
## Usage
After `CPM.cmake` has been added to your project, you can call `CPMAddPackage` for every dependency of the project with the following named parameters.
```cmake
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
CPMAddPackage(
NAME # The dependency name (usually chosen to match the target name)
VERSION # The minimum version of the dependency (optional, defaults to 0)
OPTIONS # Configuration options passed to the dependency (optional)
DOWNLOAD_ONLY # If set, the project is downloaded, but not configured (optional)
[...] # Source options, see below
)
```
project(MyParser)
The command downloads the project defined by the source options if a newer version hasn't been included before.
The source is usually a git repository, but svn and direct urls are als supported.
See the [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) documentation for all available options.
If a `GIT_TAG` hasn't been explicitly specified it defaults to `v$VERSION` which is a common convention for github projects.
After calling `CPMAddPackage`, the variables `(DEPENDENCY)_SOURCE_DIR` and `(DEPENDENCY)_BINARY_DIR` are set, where `(DEPENDENCY)` is the name of the dependency.
## Full Example
```cmake
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
# create project
project(MyProject)
# add dependencies
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPM.cmake)
include(cmake/CPM.cmake)
CPMAddPackage(
NAME LarsParser
VERSION 1.2
VERSION 1.8
GIT_REPOSITORY https://github.com/TheLartians/Parser.git
GIT_TAG master # optional
OPTIONS
"LARS_PARSER_BUILD_GLUE_EXTENSION ON"
)
# add executable
set (CMAKE_CXX_STANDARD 17)
add_executable(my-parser my-parser.cpp)
target_link_libraries(cpm-test LarsParser)
add_executable(myProject myProject.cpp)
set_target_properties(myProject PROPERTIES CXX_STANDARD 17)
target_link_libraries(myProject LarsParser)
```
# Limitations
See the [examples directory](https://github.com/TheLartians/CPM/tree/master/examples) for more examples with source code.
- First version used: in diamond dependency graphs (e.g. `A` depends on `C`(v1.1) and `A` depends on `B` depends on `C`(v1.2)) the first added dependency will be used (in this case `C`@1.1).
- No possibility not automatically update dependencies. To update a dependency, version numbers or git tags in the cmake scripts must be adapted manually.
## Adding CPM
To add CPM to your current project, simply add `cmake/CPM.cmake` to your project's `cmake` directory. The command below will perform this automatically.
```bash
wget -O cmake/CPM.cmake https://raw.githubusercontent.com/TheLartians/CPM/master/cmake/CPM.cmake
```
## Updating CPM
To update CPM to the newest version, simply update the script in the project's cmake directory, for example by running the command above. Dependencies using CPM will automatically use the updated script of the outermost project.
## Snipplets
These are some small snipplets demonstrating how to include some projects used with CPM.
### Catch2
Has a CMakeLists.txt that supports `add_subdirectory`.
```cmake
CPMAddPackage(
NAME Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
VERSION 2.5.0
)
```
### google/benchmark
Has a CMakeLists.txt that supports `add_subdirectory`, but needs some configuring to work without external dependencies.
```cmake
CPMAddPackage(
NAME benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
VERSION 1.4.1
OPTIONS
"BENCHMARK_ENABLE_TESTING Off"
)
# needed to compile with C++17
set_target_properties(benchmark PROPERTIES CXX_STANDARD 17)
```
### Lua
Has no CMakeLists.txt, so a target must be created manually.
```cmake
CPMAddPackage(
NAME lua
GIT_REPOSITORY https://github.com/lua/lua.git
VERSION 5-3-4
GIT_SHALLOW YES
DOWNLOAD_ONLY YES
)
FILE(GLOB lua_sources ${lua_SOURCE_DIR}/*.c)
add_library(lua STATIC ${lua_sources})
target_include_directories(lua
PUBLIC
$<BUILD_INTERFACE:${lua_SOURCE_DIR}>
)
```
## Local packages
CPM can be configured to use `find_package` to search for locally installed dependencies first.
If `CPM_LOCAL_PACKAGES_ONLY` is set, CPM will error when dependency is not found locally.
## Advantages
- **Small repos** CPM takes care of project dependencies, allowing you to focus on creating small, well-tested frameworks.
- **Cross-Plattform** CPM adds projects via `add_subdirectory`, which is compatible with all cmake toolchains and generators.
- **Reproducable builds** By using versioning via git tags it is ensured that a project will always be in the same state everywhere.
- **No installation required** No need to install anything. Just add the script to your project and you're good to go.
- **No Setup required** There is a good chance your existing projects already work as CPM dependencies.
- **Simple source distribution** CPM makes including projects with source files easy, reducing the need for monolithic header files.
## Limitations
- **First version used** In diamond-shaped dependency graphs (e.g. `A` depends on `C`@1.1 and `B`, which itself depends on `C`@1.2 the first added dependency will be used (in this case `C`@1.1). In this case, B requires a newer version of `C` than `A`, so CPM will emit an error. This can be resolved by updating the outermost dependency version.
- **No auto-update** To update a dependency, version must be adapted manually and there is no way for CPM to figure out the most recent version.
- **No pre-built binaries** Unless they are installed or included in the linked repository.
For projects with more complex needs and an extra setup step doesn't matter, it is worth to check out fully featured C++ package managers such as [conan](https://conan.io) or [hunter](https://github.com/ruslo/hunter) instead.

View File

@@ -1,65 +1,189 @@
set(_CPM_Dir "${CMAKE_CURRENT_LIST_DIR}")
# TheLartians/CPM - A simple Git dependency manager
# =================================================
# See https://github.com/TheLartians/CPM for usage and update instructions.
#
# MIT License
# -----------
#[[
Copyright (c) 2019 Lars Melchior
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
set(CURRENT_CPM_VERSION 0.9)
if(CPM_DIRECTORY)
if(NOT ${CPM_DIRECTORY} MATCHES ${CMAKE_CURRENT_LIST_DIR})
if (${CPM_VERSION} VERSION_LESS ${CURRENT_CPM_VERSION})
message(AUTHOR_WARNING "${CPM_INDENT} \
A dependency is using a more recent CPM (${CURRENT_CPM_VERSION}) than the current project (${CPM_VERSION}). \
It is recommended to upgrade CPM to the most recent version. \
See https://github.com/TheLartians/CPM for more information.\
")
endif()
return()
endif()
endif()
set(CPM_VERSION ${CURRENT_CPM_VERSION} CACHE INTERNAL "")
set(CPM_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "")
set(CPM_PACKAGES "" CACHE INTERNAL "")
option(CPM_USE_LOCAL_PACKAGES "Use locally installed packages (find_package)" OFF)
option(CPM_LOCAL_PACKAGES_ONLY "Use only locally installed packages" OFF)
include(FetchContent)
include(CMakeParseArguments)
include(${_CPM_Dir}/DownloadProject.cmake)
function(CPMHasPackage)
if(NOT CPM_INDENT)
set(CPM_INDENT "CPM:")
endif()
function(CPMRegisterPackage PACKAGE VERSION)
list(APPEND CPM_PACKAGES ${PACKAGE})
set(CPM_PACKAGES ${CPM_PACKAGES} CACHE INTERNAL "")
set("CPM_PACKAGE_${PACKAGE}_VERSION" ${VERSION} CACHE INTERNAL "")
endfunction()
function(CPM_GET_PACKAGE_VERSION PACKAGE)
set(CPM_PACKAGE_VERSION "${CPM_PACKAGE_${PACKAGE}_VERSION}" PARENT_SCOPE)
endfunction()
function(CPM_PARSE_OPTION OPTION)
string(REGEX MATCH "^[^ ]+" OPTION_KEY ${OPTION})
string(LENGTH ${OPTION_KEY} OPTION_KEY_LENGTH)
math(EXPR OPTION_KEY_LENGTH "${OPTION_KEY_LENGTH}+1")
string(SUBSTRING ${OPTION} "${OPTION_KEY_LENGTH}" "-1" OPTION_VALUE)
set(OPTION_KEY "${OPTION_KEY}" PARENT_SCOPE)
set(OPTION_VALUE "${OPTION_VALUE}" PARENT_SCOPE)
endfunction()
function(CPMAddPackage)
set(options QUIET)
set(oneValueArgs
NAME
GIT_REPOSITORY
VERSION
GIT_TAG
BINARY_DIR
DOWNLOAD_ONLY
)
set(multiValueArgs "")
set(multiValueArgs
OPTIONS
)
cmake_parse_arguments(CPM_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT CPM_PACKAGES)
set(CPM_PACKAGES "")
if(${CPM_USE_LOCAL_PACKAGES} OR ${CPM_LOCAL_PACKAGES_ONLY})
find_package(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION} QUIET)
if(${CPM_PACKAGE_FOUND})
message(STATUS "CPM: adding local package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION}")
set_target_properties(${CPM_ARGS_NAME}
PROPERTIES
IMPORTED_GLOBAL True
)
return()
endif()
if(${CPM_LOCAL_PACKAGES_ONLY})
message(SEND_ERROR "CPM: ${CPM_ARGS_NAME} not found via find_package(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION})")
endif()
endif()
if (NOT CPM_ARGS_BINARY_DIR)
set(CPM_ARGS_BINARY_DIR ${CMAKE_BINARY_DIR}/CPM-projects/${CPM_ARGS_NAME})
endif()
message("test: ${CPM_ARGS_BINARY_DIR}")
if (NOT CPM_PROJECT_DIR)
set(CPM_PROJECT_DIR "${CPM_ARGS_BINARY_DIR}")
if (NOT CPM_ARGS_VERSION)
set(CPM_ARGS_VERSION 0)
endif()
if (NOT CPM_ARGS_GIT_TAG)
set(CPM_ARGS_GIT_TAG v${CPM_ARGS_VERSION})
endif()
SET(CPM_TARGET_CMAKE_FILE "${CPM_PROJECT_DIR}")
if(CPM_ARGS_DOWNLOAD_ONLY)
set(DOWNLOAD_ONLY ${CPM_ARGS_DOWNLOAD_ONLY})
else()
set(DOWNLOAD_ONLY NO)
endif()
if (${CPM_ARGS_NAME} IN_LIST CPM_PACKAGES)
message(STATUS "CPM: package ${CPM_ARGS_NAME} already added")
else()
message(STATUS "CPM: adding package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION}")
# update package data
LIST(APPEND CPM_PACKAGES ${CPM_ARGS_NAME})
# save package data
set(CPM_PACKAGES "${CPM_PACKAGES}" CACHE INTERNAL "CPM Packages")
configure_file(
"${_CPM_Dir}/CPMProject.CMakeLists.cmake.in"
"${CPM_TARGET_CMAKE_FILE}/CMakeLists.txt"
@ONLY
)
CPM_GET_PACKAGE_VERSION(${CPM_ARGS_NAME})
if(${CPM_PACKAGE_VERSION} VERSION_LESS ${CPM_ARGS_VERSION})
message(WARNING "${CPM_INDENT} requires a newer version of ${CPM_ARGS_NAME} (${CPM_ARGS_VERSION}) than currently included (${CPM_PACKAGE_VERSION}).")
endif()
if (CPM_ARGS_OPTIONS)
foreach(OPTION ${CPM_ARGS_OPTIONS})
CPM_PARSE_OPTION(${OPTION})
if(NOT "${${OPTION_KEY}}" STREQUAL ${OPTION_VALUE})
message(WARNING "${CPM_INDENT} ignoring package option for ${CPM_ARGS_NAME}: ${OPTION_KEY} = ${OPTION_VALUE} (${${OPTION_KEY}})")
endif()
endforeach()
endif()
CPM_FETCH_PACKAGE(${CPM_ARGS_NAME} ${DOWNLOAD_ONLY})
CPMGetProperties(${CPM_ARGS_NAME})
SET(${CPM_ARGS_NAME}_SOURCE_DIR "${${CPM_ARGS_NAME}_SOURCE_DIR}" PARENT_SCOPE)
SET(${CPM_ARGS_NAME}_BINARY_DIR "${${CPM_ARGS_NAME}_BINARY_DIR}" PARENT_SCOPE)
return()
endif()
if (NOT TARGET ${CPM_ARGS_NAME})
add_subdirectory(${CPM_TARGET_CMAKE_FILE} ${CPM_ARGS_BINARY_DIR})
CPMRegisterPackage(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION})
if (CPM_ARGS_OPTIONS)
foreach(OPTION ${CPM_ARGS_OPTIONS})
CPM_PARSE_OPTION(${OPTION})
set(${OPTION_KEY} ${OPTION_VALUE} CACHE INTERNAL "")
endforeach()
endif()
CPM_DECLARE_PACKAGE(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION} ${CPM_ARGS_GIT_TAG} "${CPM_ARGS_UNPARSED_ARGUMENTS}")
CPM_FETCH_PACKAGE(${CPM_ARGS_NAME} ${DOWNLOAD_ONLY})
CPMGetProperties(${CPM_ARGS_NAME})
SET(${CPM_ARGS_NAME}_SOURCE_DIR "${${CPM_ARGS_NAME}_SOURCE_DIR}" PARENT_SCOPE)
SET(${CPM_ARGS_NAME}_BINARY_DIR "${${CPM_ARGS_NAME}_BINARY_DIR}" PARENT_SCOPE)
endfunction()
function (CPM_DECLARE_PACKAGE PACKAGE VERSION GIT_TAG)
message(STATUS "${CPM_INDENT} adding package ${PACKAGE}@${VERSION} (${GIT_TAG})")
FetchContent_Declare(
${PACKAGE}
GIT_TAG ${GIT_TAG}
${ARGN}
)
endfunction()
function (CPM_FETCH_PACKAGE PACKAGE DOWNLOAD_ONLY)
set(CPM_OLD_INDENT "${CPM_INDENT}")
set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:")
if(${DOWNLOAD_ONLY})
if(NOT "${PACKAGE}_POPULATED")
FetchContent_Populate(${PACKAGE})
endif()
else()
FetchContent_MakeAvailable(${PACKAGE})
endif()
set(CPM_INDENT "${CPM_OLD_INDENT}")
endfunction()
function (CPMGetProperties PACKAGE)
FetchContent_GetProperties(${PACKAGE})
string(TOLOWER ${PACKAGE} lpackage)
SET(${PACKAGE}_SOURCE_DIR "${${lpackage}_SOURCE_DIR}" PARENT_SCOPE)
SET(${PACKAGE}_BINARY_DIR "${${lpackage}_BINARY_DIR}" PARENT_SCOPE)
endfunction()

View File

@@ -1,27 +0,0 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
if(TARGET @CPM_ARGS_NAME@)
return()
endif()
find_package(@CPM_ARGS_NAME@ @CPM_ARGS_VERSION@ QUIET)
if(${PACKAGE_FOUND})
set_target_properties(@CPM_ARGS_NAME@
PROPERTIES
IMPORTED_GLOBAL True
)
else()
download_project(
PROJ @CPM_ARGS_NAME@
GIT_REPOSITORY @CPM_ARGS_GIT_REPOSITORY@
GIT_TAG @CPM_ARGS_GIT_TAG@
UPDATE_DISCONNECTED 1
GIT_SHALLOW 1
PREFIX @CPM_ARGS_BINARY_DIR@/dl
QUIET
)
add_subdirectory(${@CPM_ARGS_NAME@_SOURCE_DIR} ${@CPM_ARGS_NAME@_BINARY_DIR})
endif()

View File

@@ -1,17 +0,0 @@
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
cmake_minimum_required(VERSION 2.8.2)
project(${DL_ARGS_PROJ}-download NONE)
include(ExternalProject)
ExternalProject_Add(${DL_ARGS_PROJ}-download
${DL_ARGS_UNPARSED_ARGUMENTS}
SOURCE_DIR "${DL_ARGS_SOURCE_DIR}"
BINARY_DIR "${DL_ARGS_BINARY_DIR}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

View File

@@ -1,182 +0,0 @@
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
#
# MODULE: DownloadProject
#
# PROVIDES:
# download_project( PROJ projectName
# [PREFIX prefixDir]
# [DOWNLOAD_DIR downloadDir]
# [SOURCE_DIR srcDir]
# [BINARY_DIR binDir]
# [QUIET]
# ...
# )
#
# Provides the ability to download and unpack a tarball, zip file, git repository,
# etc. at configure time (i.e. when the cmake command is run). How the downloaded
# and unpacked contents are used is up to the caller, but the motivating case is
# to download source code which can then be included directly in the build with
# add_subdirectory() after the call to download_project(). Source and build
# directories are set up with this in mind.
#
# The PROJ argument is required. The projectName value will be used to construct
# the following variables upon exit (obviously replace projectName with its actual
# value):
#
# projectName_SOURCE_DIR
# projectName_BINARY_DIR
#
# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically
# need to be provided. They can be specified if you want the downloaded source
# and build directories to be located in a specific place. The contents of
# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the
# locations used whether you provide SOURCE_DIR/BINARY_DIR or not.
#
# The DOWNLOAD_DIR argument does not normally need to be set. It controls the
# location of the temporary CMake build used to perform the download.
#
# The PREFIX argument can be provided to change the base location of the default
# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments
# are provided, then PREFIX will have no effect. The default value for PREFIX is
# CMAKE_BINARY_DIR.
#
# The QUIET option can be given if you do not want to show the output associated
# with downloading the specified project.
#
# In addition to the above, any other options are passed through unmodified to
# ExternalProject_Add() to perform the actual download, patch and update steps.
# The following ExternalProject_Add() options are explicitly prohibited (they
# are reserved for use by the download_project() command):
#
# CONFIGURE_COMMAND
# BUILD_COMMAND
# INSTALL_COMMAND
# TEST_COMMAND
#
# Only those ExternalProject_Add() arguments which relate to downloading, patching
# and updating of the project sources are intended to be used. Also note that at
# least one set of download-related arguments are required.
#
# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to
# prevent a check at the remote end for changes every time CMake is run
# after the first successful download. See the documentation of the ExternalProject
# module for more information. It is likely you will want to use this option if it
# is available to you. Note, however, that the ExternalProject implementation contains
# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when
# using the URL download method or when specifying a SOURCE_DIR with no download
# method. Fixes for these have been created, the last of which is scheduled for
# inclusion in CMake 3.8.0. Details can be found here:
#
# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c
# https://gitlab.kitware.com/cmake/cmake/issues/16428
#
# If you experience build errors related to the update step, consider avoiding
# the use of UPDATE_DISCONNECTED.
#
# EXAMPLE USAGE:
#
# include(DownloadProject)
# download_project(PROJ googletest
# GIT_REPOSITORY https://github.com/google/googletest.git
# GIT_TAG master
# UPDATE_DISCONNECTED 1
# QUIET
# )
#
# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
#
#========================================================================================
set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}")
include(CMakeParseArguments)
function(download_project)
set(options QUIET)
set(oneValueArgs
PROJ
PREFIX
DOWNLOAD_DIR
SOURCE_DIR
BINARY_DIR
# Prevent the following from being passed through
CONFIGURE_COMMAND
BUILD_COMMAND
INSTALL_COMMAND
TEST_COMMAND
)
set(multiValueArgs "")
cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Hide output if requested
if (DL_ARGS_QUIET)
set(OUTPUT_QUIET "OUTPUT_QUIET")
else()
unset(OUTPUT_QUIET)
message(STATUS "Downloading/updating ${DL_ARGS_PROJ}")
endif()
# Set up where we will put our temporary CMakeLists.txt file and also
# the base point below which the default source and binary dirs will be.
# The prefix must always be an absolute path.
if (NOT DL_ARGS_PREFIX)
set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}")
else()
get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if (NOT DL_ARGS_DOWNLOAD_DIR)
set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download")
endif()
# Ensure the caller can know where to find the source and build directories
if (NOT DL_ARGS_SOURCE_DIR)
set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src")
endif()
if (NOT DL_ARGS_BINARY_DIR)
set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build")
endif()
set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE)
set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE)
# The way that CLion manages multiple configurations, it causes a copy of
# the CMakeCache.txt to be copied across due to it not expecting there to
# be a project within a project. This causes the hard-coded paths in the
# cache to be copied and builds to fail. To mitigate this, we simply
# remove the cache if it exists before we configure the new project. It
# is safe to do so because it will be re-generated. Since this is only
# executed at the configure step, it should not cause additional builds or
# downloads.
file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt")
# Create and build a separate CMake project to carry out the download.
# If we've already previously done these steps, they will not cause
# anything to be updated, so extra rebuilds of the project won't occur.
# Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
# has this set to something not findable on the PATH.
configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in"
"${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt")
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
-D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}"
.
RESULT_VARIABLE result
${OUTPUT_QUIET}
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
)
if(result)
message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
${OUTPUT_QUIET}
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
)
if(result)
message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}")
endif()
endfunction()

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
# ---- Dependencies ----
include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME fibonacci
GIT_REPOSITORY https://github.com/TheLartians/Fibonacci.git
VERSION 1.0
)
CPMAddPackage(
NAME benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
VERSION 1.4.1
OPTIONS
"BENCHMARK_ENABLE_TESTING Off"
)
# patch google benchmark target
set_target_properties(benchmark PROPERTIES CXX_STANDARD 17)
# ---- Executable ----
add_executable(CPMExampleBenchmark "main.cpp")
set_target_properties(CPMExampleBenchmark PROPERTIES CXX_STANDARD 17)
target_link_libraries(CPMExampleBenchmark fibonacci benchmark)

View File

@@ -0,0 +1,36 @@
#include <benchmark/benchmark.h>
#include <vector>
#include <algorithm>
#include <random>
#include <fibonacci.h>
std::vector<unsigned> createTestNumbers(){
std::vector<unsigned> v;
for (int i=0;i<25;++i) v.emplace_back(i);
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
return v;
}
void fibonnacci(benchmark::State& state) {
auto numbers = createTestNumbers();
for (auto _ : state) {
for (auto v: numbers) benchmark::DoNotOptimize(fibonnacci(v));
}
}
BENCHMARK(fibonnacci);
void fastFibonacci(benchmark::State& state) {
auto numbers = createTestNumbers();
for (auto _ : state) {
for (auto v: numbers) benchmark::DoNotOptimize(fastFibonacci(v));
}
}
BENCHMARK(fastFibonacci);
BENCHMARK_MAIN();

View File

@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
# ---- Options ----
option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF)
# ---- Dependencies ----
include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME fibonacci
GIT_REPOSITORY https://github.com/TheLartians/Fibonacci.git
VERSION 1.0
)
CPMAddPackage(
NAME Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
VERSION 2.5.0
)
# ---- Create binary ----
add_executable(CPMExampleCatch2 main.cpp)
target_link_libraries(CPMExampleCatch2 fibonacci Catch2)
set_target_properties(CPMExampleCatch2 PROPERTIES CXX_STANDARD 17 COMPILE_FLAGS "-Wall -pedantic -Wextra -Werror")
# ---- Enable testing ----
ENABLE_TESTING()
ADD_TEST(CPMExampleCatch2 CPMExampleCatch2)
# ---- Add code coverage ----
if (${ENABLE_TEST_COVERAGE})
set_target_properties(CPMExampleCatch2 PROPERTIES CXX_STANDARD 17 COMPILE_FLAGS "-O0 -g -fprofile-arcs -ftest-coverage --coverage")
target_link_options(CPMExampleCatch2 PUBLIC "--coverage")
endif()

20
examples/catch2/main.cpp Normal file
View File

@@ -0,0 +1,20 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#include <fibonacci.h>
TEST_CASE("fibonnacci"){
REQUIRE(fibonnacci(0) == 0);
REQUIRE(fibonnacci(1) == 1);
REQUIRE(fibonnacci(2) == 1);
REQUIRE(fibonnacci(3) == 2);
REQUIRE(fibonnacci(4) == 3);
REQUIRE(fibonnacci(5) == 5);
REQUIRE(fibonnacci(13) == 233);
}
TEST_CASE("fastFibonnacci"){
for (unsigned i=0; i<25; ++i){
REQUIRE(fibonnacci(i) == fastFibonacci(i));
}
}

View File

@@ -0,0 +1,41 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
# ---- Options ----
option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF)
# ---- Dependencies ----
include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME fibonacci
GIT_REPOSITORY https://github.com/TheLartians/Fibonacci.git
VERSION 1.0
)
CPMAddPackage(
NAME doctest
GIT_REPOSITORY https://github.com/onqtam/doctest.git
VERSION 2.3.2
GIT_TAG 2.3.2
GIT_SHALLOW True
)
# ---- Create binary ----
add_executable(CPMExampleDoctest main.cpp)
target_link_libraries(CPMExampleDoctest fibonacci doctest)
set_target_properties(CPMExampleDoctest PROPERTIES CXX_STANDARD 17 COMPILE_FLAGS "-Wall -pedantic -Wextra -Werror")
# ---- Enable testing ----
ENABLE_TESTING()
ADD_TEST(CPMExampleDoctest CPMExampleDoctest)
# ---- Add code coverage ----
if (${ENABLE_TEST_COVERAGE})
set_target_properties(CPMExampleDoctest PROPERTIES CXX_STANDARD 17 COMPILE_FLAGS "-O0 -g -fprofile-arcs -ftest-coverage --coverage")
target_link_options(CPMExampleDoctest PUBLIC "--coverage")
endif()

20
examples/doctest/main.cpp Normal file
View File

@@ -0,0 +1,20 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>
#include <fibonacci.h>
TEST_CASE("fibonnacci"){
CHECK(fibonnacci(0) == 0);
CHECK(fibonnacci(1) == 1);
CHECK(fibonnacci(2) == 1);
CHECK(fibonnacci(3) == 2);
CHECK(fibonnacci(4) == 3);
CHECK(fibonnacci(5) == 5);
CHECK(fibonnacci(13) == 233);
}
TEST_CASE("fastFibonnacci"){
for (unsigned i=0; i<25; ++i){
CHECK(fibonnacci(i) == fastFibonacci(i));
}
}

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
include(../../cmake/CPM.cmake)
# ---- Dependencies ----
CPMAddPackage(
NAME Glue
GIT_REPOSITORY https://github.com/TheLartians/Glue.git
VERSION 0.8.1
OPTIONS
"GLUE_ENABLE_LUA ON"
"GLUE_BUILD_LUA ON"
)
CPMAddPackage(
NAME LarsParser
GIT_REPOSITORY https://github.com/TheLartians/Parser.git
VERSION 1.9
OPTIONS
"LARS_PARSER_BUILD_GLUE_EXTENSION ON"
)
# ---- Create binary ----
add_executable(parser-lua main.cpp)
set_target_properties(parser-lua PROPERTIES CXX_STANDARD 17)
target_link_libraries(parser-lua LHC LarsParser Glue)

View File

@@ -0,0 +1,46 @@
#include <lars/parser/extension.h>
#include <glue/lua.h>
#include <stdexcept>
#include <iostream>
int main() {
auto lua = glue::LuaState();
lua.openStandardLibs();
lua["parser"] = lars::glue::parser();
lua.run(R"(
wordParser = parser.Program.create()
wordParser:setRule("Whitespace", "[ \t]")
wordParser:setSeparatorRule("Whitespace")
wordParser:setRule("Word", "[a-zA-Z]+")
wordParser:setRuleWithCallback("Words", "Word*", function(e)
local N = e:size()
local res = {}
for i=0,N-1 do res[#res+1] = e:get(i):string() end
return res
end)
wordParser:setStartRule("Words")
)");
lua.run(R"(
while true do
print("please enter some words or 'quit' to exit");
local input = io.read();
if input == "quit" then os.exit() end
local result
ok, err = pcall(function() result = wordParser:run(input) end)
if ok then
print("you entered " .. #result .. " words!")
else
print("error: " .. tostring(err))
end
end
)");
return 0;
}

View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# add dependencies
include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME LarsParser
GIT_REPOSITORY https://github.com/TheLartians/Parser.git
VERSION 1.7
)
# add executable
add_executable(calculator main.cpp)
set_target_properties(calculator PROPERTIES CXX_STANDARD 17)
target_link_libraries(calculator LarsParser)

57
examples/parser/main.cpp Normal file
View File

@@ -0,0 +1,57 @@
#include <iostream>
#include <unordered_map>
#include <cmath>
#include <lars/parser/generator.h>
int main() {
using namespace std;
using VariableMap = unordered_map<string, float>;
lars::ParserGenerator<float, VariableMap &> calculator;
auto &g = calculator;
g.setSeparator(g["Whitespace"] << "[\t ]");
g["Expression"] << "Set | Sum";
g["Set" ] << "Name '=' Sum" >> [](auto e, auto &v){ return v[e[0].string()] = e[1].evaluate(v); };
g["Sum" ] << "Add | Subtract | Product";
g["Product" ] << "Multiply | Divide | Exponent";
g["Exponent" ] << "Power | Atomic";
g["Atomic" ] << "Number | Brackets | Variable";
g["Brackets" ] << "'(' Sum ')'";
g["Add" ] << "Sum '+' Product" >> [](auto e, auto &v){ return e[0].evaluate(v) + e[1].evaluate(v); };
g["Subtract" ] << "Sum '-' Product" >> [](auto e, auto &v){ return e[0].evaluate(v) - e[1].evaluate(v); };
g["Multiply" ] << "Product '*' Exponent" >> [](auto e, auto &v){ return e[0].evaluate(v) * e[1].evaluate(v); };
g["Divide" ] << "Product '/' Exponent" >> [](auto e, auto &v){ return e[0].evaluate(v) / e[1].evaluate(v); };
g["Power" ] << "Atomic ('^' Exponent)" >> [](auto e, auto &v){ return pow(e[0].evaluate(v), e[1].evaluate(v)); };
g["Variable" ] << "Name" >> [](auto e, auto &v){ return v[e[0].string()]; };
g["Name" ] << "[a-zA-Z] [a-zA-Z0-9]*";
g["Number" ] << "'-'? [0-9]+ ('.' [0-9]+)?" >> [](auto e, auto &){ return stod(e.string()); };
g.setStart(g["Expression"]);
cout << "Enter an expression to be evaluated or 'quit' to exit.\n";
VariableMap variables;
while (true) {
string str;
cout << "> ";
getline(cin,str);
if(str == "q" || str == "quit"){ break; }
try {
auto result = calculator.run(str, variables);
cout << str << " = " << result << endl;
} catch (lars::SyntaxError &error) {
auto syntax = error.syntax;
cout << " ";
cout << string(syntax->begin, ' ');
cout << string(syntax->length(), '~');
cout << "^\n";
cout << " " << "Syntax error while parsing " << syntax->rule->name << endl;
}
}
return 0;
}

29
examples/run_all.py Normal file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/python3
from pathlib import Path
from subprocess import PIPE, run
examples = [
x for x in Path(__file__).parent.iterdir() if x.is_dir() and (x / 'CMakeLists.txt').exists()
]
assert(len(examples) > 0)
def runCommand(command):
print('- %s' % command)
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
if result.returncode != 0:
print("error while running '%s':\n" % command, ' ' + str(result.stderr).replace('\n','\n '))
exit(result.returncode)
return result.stdout
print('')
for example in examples:
print("running example %s" % example.name)
print("================" + ('=' * len(example.name)))
project = Path(".") / 'build' / example.name
configure = runCommand('cmake -H%s -B%s -DCMAKE_BUILD_TYPE=RelWithDebInfo' % (example, project))
print(' ' + '\n '.join([line for line in configure.split('\n') if 'CPM:' in line]))
build = runCommand('cmake --build %s -j4' % (project))
print(' ' + '\n '.join([line for line in build.split('\n') if 'Built target' in line]))
print('')

View File

@@ -1,41 +0,0 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(CPMTest)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/CPM.cmake)
CPMAddPackage(
NAME LHC
GIT_REPOSITORY https://github.com/TheLartians/LHC.git
VERSION 0.3
)
CPMAddPackage(
NAME LarsEvent
GIT_REPOSITORY https://github.com/TheLartians/Event.git
VERSION 1.0
GIT_TAG master
)
# Add project that depends on previous project
CPMAddPackage(
NAME LarsParser
GIT_REPOSITORY https://github.com/TheLartians/Parser.git
VERSION 1.3
)
# add project twice
CPMAddPackage(
NAME LHC
GIT_REPOSITORY https://github.com/TheLartians/LHC.git
VERSION 0.3
)
# add executable
set (CMAKE_CXX_STANDARD 17)
add_executable(cpm-test test.cpp)
target_link_libraries(cpm-test LHC LarsEvent LarsParser)
# tests
enable_testing()
add_test(cpm-test cpm-test)

View File

@@ -1,32 +0,0 @@
#include <lars/parser_generator.h>
#include <lars/event.h>
int main() {
// Define the return value
int result = 1;
// Define grammar and evaluation rules
lars::ParserGenerator<float> g;
g.setSeparator(g["Whitespace"] << "[\t ]");
g["Sum" ] << "Add | Subtract | Product";
g["Product" ] << "Multiply | Divide | Atomic";
g["Atomic" ] << "Number | '(' Sum ')'";
g["Add" ] << "Sum '+' Product" >> [](auto e){ return e[0].evaluate() + e[1].evaluate(); };
g["Subtract"] << "Sum '-' Product" >> [](auto e){ return e[0].evaluate() - e[1].evaluate(); };
g["Multiply"] << "Product '*' Atomic" >> [](auto e){ return e[0].evaluate() * e[1].evaluate(); };
g["Divide" ] << "Product '/' Atomic" >> [](auto e){ return e[0].evaluate() / e[1].evaluate(); };
g["Number" ] << "'-'? [0-9]+ ('.' [0-9]+)?" >> [](auto e){ return stof(e.string()); };
g.setStart(g["Sum"]);
// Execute a string
// create an event
lars::Event<float> onResult;
onResult.connect([&](float v){ result = !(int(v) == 5); });
// emit the result of a parsed string
onResult.notify(g.run("1 + 2 * (3+4)/2 - 3"));
// return the result
return result;
}

View File

@@ -1,21 +0,0 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(CPMTest)
# add dependencies
include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/CPM.cmake)
CPMAddPackage(
NAME LarsParser
GIT_REPOSITORY https://github.com/TheLartians/Parser.git
VERSION 1.3
)
# add executable
set (CMAKE_CXX_STANDARD 17)
add_executable(cpm-test test.cpp)
target_link_libraries(cpm-test LarsParser)
# tests
enable_testing()
add_test(cpm-test cpm-test)

View File

@@ -1,27 +0,0 @@
#include <lars/parser_generator.h>
int main() {
lars::ParserGenerator<float> g;
// Define grammar and evaluation rules
g.setSeparator(g["Whitespace"] << "[\t ]");
g["Sum" ] << "Add | Subtract | Product";
g["Product" ] << "Multiply | Divide | Atomic";
g["Atomic" ] << "Number | '(' Sum ')'";
g["Add" ] << "Sum '+' Product" >> [](auto e){ return e[0].evaluate() + e[1].evaluate(); };
g["Subtract"] << "Sum '-' Product" >> [](auto e){ return e[0].evaluate() - e[1].evaluate(); };
g["Multiply"] << "Product '*' Atomic" >> [](auto e){ return e[0].evaluate() * e[1].evaluate(); };
g["Divide" ] << "Product '/' Atomic" >> [](auto e){ return e[0].evaluate() / e[1].evaluate(); };
g["Number" ] << "'-'? [0-9]+ ('.' [0-9]+)?" >> [](auto e){ return stof(e.string()); };
g.setStart(g["Sum"]);
// Execute a string
float result = g.run("1 + 2 * (3+4)/2 - 3");
// validate result
if (result == 5) {
return 0;
} else {
return 1;
}
}