C++
This is a template for C++ projects.
Contents
Directory Structure
- Code used for testing is separated from the actual source code
- A directory exists for each namespace
Markdown
Markdown is a lightweight markup language for text formatting.
Each project should include a readme file with the following information:
- Description about the project
- How the software can be build
- Information about running the tests
- Usage example to get started
README.md
-
# HelloWorld This application prints *Hello World!* on screen. The intention is to have a template for C++ projects. ## How to build ### CMake ``` mkdir build cd build cmake .. cmake --build . ``` ### Conan ``` mkdir build cd build conan install --build=missing .. conan build .. ``` ## Running the tests ``` cd build ctest ``` ## Usage ``` cd build ./bin/hello [name] ```
- https://en.wikipedia.org/wiki/Markdown
- https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
CMake
CMake is the de facto standard build system for C++.
CMakeLists.txt
-
cmake_minimum_required(VERSION 3.1) project(HelloWorld) include(CTest) include(${CMAKE_BINARY_DIR}/conan_paths.cmake OPTIONAL) find_package(Boost REQUIRED) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) include_directories(src) add_subdirectory(src) if(BUILD_TESTING) enable_testing() add_subdirectory(test) endif()
src/CMakeLists.txt
-
add_subdirectory(util) set(hello_SOURCES main.cpp) add_executable(hello ${hello_SOURCES}) target_link_libraries(hello util) install(TARGETS hello RUNTIME DESTINATION bin)
src/util/CMakeLists.txt
-
set(util_HEADERS simple_replacer.hpp) set(util_SOURCES simple_replacer.cpp) add_library(util ${util_SOURCES} ${util_HEADERS}) set_target_properties(util PROPERTIES PUBLIC_HEADER "${util_HEADERS}") target_include_directories(util PRIVATE ${Boost_INCLUDE_DIRS}) target_link_libraries(util ${Boost_LIBRARIES}) install(TARGETS util ARCHIVE DESTINATION lib LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include/util)
test/CMakeLists.txt
-
add_subdirectory(util)
test/util/CMakeLists.txt
-
add_executable(simple_replacer_test simple_replacer_test.cpp) target_link_libraries(simple_replacer_test util) add_test(NAME simple_replacer COMMAND simple_replacer_test)
- https://cmake.org/cmake/help/latest/
- https://cmake.org/cmake/help/latest/module/CTest.html
- https://cmake.org/cmake/help/latest/command/install.html#installing-targets
Conan
Conan is a package manager for C++.
conanfile.py
-
from conans import ConanFile, CMake, tools class HelloWorldConan(ConanFile): name = "HelloWorld" settings = "os", "compiler", "build_type", "arch" options = { "shared": [True, False], "build_tests": [True, False] } default_options = { "shared": False, "build_tests": True } build_requires = ( "boost/1.67.0@conan/stable" ) generators = "cmake_paths" scm = { "type": "git", "url": "auto", "revision": "auto" } def set_version(self): try: git = tools.Git(folder=self.recipe_folder) tag = git.get_tag() if tag: if tag[0] == 'v': self.version = tag[1:] else: self.version = tag else: self.version = git.get_revision()[:7] except Exception as ex: print("Exception in set_version(): "+str(ex)) self.version = "undef" def _configure_cmake(self): cmake = CMake(self) # cmake.generator = "Ninja" # cmake.definitions['CMAKE_BUILD_TYPE'] = self.settings.build_type if not self.options.build_tests: cmake.definitions['BUILD_TESTING'] = 'OFF' cmake.configure() return cmake def build(self): cmake = self._configure_cmake() cmake.build() def package(self): cmake = self._configure_cmake() cmake.install()
- https://docs.conan.io/en/latest/mastering/conanfile_py.html
- https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_paths_generator.html
- https://docs.conan.io/en/latest/howtos/capture_version.html
- https://docs.conan.io/en/latest/howtos/cmake_install.html
Git
Git is a version control system that tracks changes in code.
The build directory is excluded from tracking changes.
.gitignore
-
build
Clang-Format
Clang-Format is a tool to format code.
.clang-format
-
BasedOnStyle: WebKit NamespaceIndentation: None
Header Files
src/util/simple_replacer.hpp
-
#pragma once #include <string> namespace util { class SimpleReplacer { public: explicit SimpleReplacer(const std::string& content); virtual ~SimpleReplacer(); void replaceAll(const std::string& search, const std::string& replace); std::string getContent() const; private: std::string content_; }; } // namespace util
Source Files
src/main.cpp
-
#include "util/simple_replacer.hpp" #include <iostream> #include <string> int main(int argc, char* argv[]) { std::string msg("Hello World!"); if (argc >= 2) { util::SimpleReplacer replacer(msg); replacer.replaceAll("World", argv[1]); msg = replacer.getContent(); } std::cout << msg << std::endl; }
src/util/simple_replacer.cpp
-
#include "simple_replacer.hpp" #include <boost/algorithm/string.hpp> namespace util { SimpleReplacer::SimpleReplacer(const std::string& content) : content_(content) { } SimpleReplacer::~SimpleReplacer() = default; void SimpleReplacer::replaceAll(const std::string& search, const std::string& replace) { boost::replace_all(content_, search, replace); } std::string SimpleReplacer::getContent() const { return content_; } } // namespace util
test/util/simple_replacer_test.cpp
-
#include "util/simple_replacer.hpp" int main() { std::string content("Just a test."); util::SimpleReplacer replacer(content); replacer.replaceAll("a", "another"); std::string result = replacer.getContent(); std::string expected("Just another test."); if (result == expected) { return 0; } return 1; }
CONTENT.html | source | 2022-05-22 | 11.2 KB |
HelloWorld-0.1.0.tar.gz | sha256 | 2020-12-15 | 2.3 KB |