Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
cmake_minimum_required(VERSION 3.22)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export compile commands so cppcheck is aware of compiler options and paths

# Define the project name.
project(basicSetup)
Expand All @@ -21,4 +22,32 @@ add_subdirectory(api)
add_executable(basicSetup main.cpp)

# Add libraries
target_link_libraries(basicSetup PUBLIC kernel api)
target_link_libraries(basicSetup PUBLIC kernel api)

# Set up cppcheck
# Set up cppcheck build directory and cache
set(CPPCHECK_BUILD_DIR "${CMAKE_BINARY_DIR}/cppcheck")
file(MAKE_DIRECTORY "${CPPCHECK_BUILD_DIR}" "${CPPCHECK_BUILD_DIR}/cache")
find_program(CPPCHECK_EXECUTABLE NAMES cppcheck)

set(CPPCHECK_ARGS
--enable=all
--check-level=exhaustive
--inline-suppr
--max-configs=120
--std=c++${CMAKE_CXX_STANDARD} # use the standard from cmake
--cppcheck-build-dir="${CPPCHECK_BUILD_DIR}/cache"
--project="${CMAKE_BINARY_DIR}/compile_commands.json"
--suppress=missingIncludeSystem
)

if(CPPCHECK_EXECUTABLE)
message(STATUS "Found cppcheck: ${CPPCHECK_EXECUTABLE}")
add_custom_target(
cppcheck
COMMAND ${CPPCHECK_EXECUTABLE} ${CPPCHECK_ARGS}
COMMENT "Running cppcheck static analysis"
)
else()
message(WARNING "cppcheck not found. Static analysis will be skipped.")
endif()
14 changes: 13 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@
},
"configurePresets": [
{
"name": "windows-default",
"name": "win-msbuild",
"displayName": "Windows x64 Debug",
"description": "Sets msvc generator, compilers, x64 architecture, build and install directory, debug build type",
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "win-ninja",
"displayName": "Windows x64 Debug Ninja",
"description": "Sets ninja generator, compilers, x64 architecture, build and install directory, debug build type",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl"
}
}
]
}
44 changes: 37 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,62 @@
This is a repository that represents a basic, minimal, c++ project setup using cmake and conda. This currently includes:
- Creation of a `kernel` library.
- Creation of an `api` library to expose this `kernel` library.
- Creation of a python interface to enable access to the `api` from python.
- Creation of a python interface to enable access to the `api` from python using pybind.
- Creation of a second python interface using boost (rough first pass)
- cppcheck

Currently only building on windows using `msbuild` has been tested.
Currently only building on windows using `msbuild` and `ninja` has been tested.
Instructions to this regard are in the following section.

## Pre-setup requirements

- Clone this repository
- Ensure `conda` (or preferably `mamba`) is installed.
- Ensure `msbuildtools` are available, and on the path.

## Pre-setup msbuild only

## Setup
- Ensure `msbuildtools` are available, and on the path. These are typically in: `/c/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin`


## Setup msbuild

1. From repository root, create conda environment: `conda env create -f environment.yml`.
This will create a conda environment called `basic-setup`

2. Activate this conda environment: `conda activate basic-setup`.

3. Run cmake: `cmake --preset windows-default`
3. Run cmake: `cmake --preset win-ninja`

4. From the created `build` folder, run `msbuild`: `msbuild basicSetup.sln`
4. From the created `build` directory, run `msbuild`: `msbuild basicSetup.sln`

5. Add the directory of the created python interface to the python path: `set PYTHONPATH=%PYTHONPATH%;<repo root>\build\lib\Debug`

## Setup ninja

1. On windows this setup must be undertaken using `x64 Native Tools Command Prompt for VS 2022`.

2. From repository root, create conda environment: `conda env create -f environment.yml`.
This will create a conda environment called `basic-setup`

3. Activate this conda environment: `conda activate basic-setup`.

4. Run cmake: `cmake --preset win-ninja`

5. From the created `build` directory, run `ninja`

6. Add the directory of the created python interface to the python path: `set PYTHONPATH=%PYTHONPATH%;<repo root>\build\lib`

## Testing the repo setup

1. To test that the setup has been successfull, from the repository root run: `python -c "from basicSetupApi import helloWorld; helloWorld(<your name>)"`
1. To test that the setup has been successfull, from the repository root run: `python -c "from basicSetupApi import helloWorld; helloWorld('<your name>')"`

2. Alternatively (for boost api): `python -c "from api_boost import ComplexNumber; (ComplexNumber(2,5) + ComplexNumber(3,4)).print()"`

## Running cppcheck

1. As of the latest version of cppcheck on `conda-forge`, `2.15.0`, there is a bug causing cppcheck to look for `cfg` files in the wrong location:
https://github.com/conda-forge/cppcheck-feedstock/issues/19
To circumvent this, we must copy the `cfg` directory from `/c/Users/<user>/AppData/Local/mambaforge/envs/basic-setup/share/Cppcheck/cfg` to a location on the
path that cppcheck searches: `C:/Users/<user>/AppData/Local/mambaforge/envs/basic-setup/Library/bin/cfg`

2. From the `build` directory, run `cmake --build . --target cppcheck`
12 changes: 11 additions & 1 deletion api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@ target_link_libraries(api PRIVATE kernel)

# Setup python interface and link API lib
pybind11_add_module(basicSetupApi ${CMAKE_CURRENT_SOURCE_DIR}/pythonInterface/apiBindings.cpp)
target_link_libraries(basicSetupApi PRIVATE api)
target_link_libraries(basicSetupApi PRIVATE api)

### Boost Python API
find_package(Boost REQUIRED COMPONENTS python312)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)

# Create boost api library
add_library(api_boost MODULE ${CMAKE_CURRENT_SOURCE_DIR}/pythonInterface/apiBindingsBoost.cpp)
target_include_directories(api_boost PRIVATE ${Boost_INCLUDE_DIRS} ${Python3_INCLUDE_DIRS})
target_link_libraries(api_boost PRIVATE Boost::boost Boost::python312 ${Python3_LIBRARIES})
set_target_properties(api_boost PROPERTIES PREFIX "" SUFFIX ".pyd")
2 changes: 1 addition & 1 deletion api/inc/basicSetupApi/helloWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace basicSetup::api{
class helloWorld{
public:
helloWorld();
helloWorld(const std::string &name);
explicit helloWorld(const std::string &name);

private:
void _print(const std::string &name = "") const;
Expand Down
38 changes: 38 additions & 0 deletions api/pythonInterface/apiBindingsBoost.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <boost/python.hpp>
#include <iostream>

class ComplexNumber {
private:
double m_real;
double m_imaginary;

public:
ComplexNumber() : m_real(0), m_imaginary(0) {};
ComplexNumber(double real, double imaginary) : m_real(real), m_imaginary(imaginary) {};
const double getReal() const { return m_real; }
const double getImaginary() const { return m_imaginary; }

ComplexNumber ComplexNumber::operator+(const ComplexNumber& rhs) {
std::cout << "operator+ executed" << std::endl;
return ComplexNumber(m_real + rhs.getReal(), m_imaginary + rhs.getImaginary());
}
ComplexNumber ComplexNumber::operator-(const ComplexNumber& rhs) {
std::cout << "operator- executed" << std::endl;
return ComplexNumber(m_real - rhs.getReal(), m_imaginary - rhs.getImaginary());
}
void print() const { std::cout << m_real << " + " << m_imaginary << "i"; }
};

int add(int a, int b) {
return a + b;
}

BOOST_PYTHON_MODULE(api_boost) {
using namespace boost::python;
def("add", add);

class_<ComplexNumber>("ComplexNumber", init<double, double>())
.def(self - self)
.def(self + self)
.def("print", &ComplexNumber::print);
}
8 changes: 6 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: basic-setup

dependencies:
- python
- python==3.12
- pybind11
- cmake
- cmake
- libboost-devel
- libboost-python-devel
- cppcheck==2.15.0
- ninja
2 changes: 1 addition & 1 deletion kernel/inc/basicSetupKernel/printer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace basicSetup::kernel{
class printer{
public:
printer(const std::string &str);
explicit printer(const std::string &str);

private:
void _print(const std::string &str) const;
Expand Down