Native Utility
The cross-platform C++20 command line tool template.
Usage
Make sure you are signed in to your GitHub account, then just click here to use template.
Download
GitHub CI automatically generates versions of the application for different operating systems. See the Actions Tab.
Build
We need GCC or LLVM or Visual Studio toolchain, and xmake build system.
xmake
After that, we can run the release app:
./build/main/app
Containerization
To build the image, we need Docker installed:
docker build . -t app
After that, we can run the app in the container (if needed):
docker run -v `pwd`:`pwd` -w `pwd` -it --rm -p 80:80 app
To clean up Docker use docker system prune -fa
Interop with Java
See JNR project.
Development with IDE
Some IDEs require a project configuration in a specific format. You can configure project with other build system:
-
CLion, VS Code:
xmake project -k cmake
-
Visual Studio
xmake project -k vc
-
Xcode:
xmake project -k xcode
-
For someone else see:
xmake project -h
Code style & Conventions
- The entry point must be located in the
./src/main/cpp/Main.cpp
file for correct build script work. - Use functional style.
auto x = User("John"); // good, functional auto x = User{"John"}; // bad, no need '{..}' with functional initialization. User x = User("John"); // bad, old style! auto listUsers() -> vector<User> {} // good, clean code void listUsers(vector<User> to&) {} // bad, C++03 old style
- Always use const lvalue (const T &)
or TriviallyCopyable for readonly parameters.
auto readFrom(const Book &book) {} // good, no copy auto readFrom(Book book) {} // bad, copying! auto print(string_view text) {} // good, no copy auto print(string text) {} // bad, copying!
- To initialize resources, we're using modern parameter passing by value, rather
than a constant link.
class Example { private: data field; public: Example(data v): field(move(v)) {} // good, no copy Example(const data &v): field(v) {} // bad, copying! };
- Do not use
return move(v)
! Use NRVO instead. - Use rvalue links (T &&) only in move constructors.
class Example { <...> public: Example(Example &&other): data(move(other.data)) {} // good, move resources. Example(AnotherType &&v): field(v) {} // very bad! Use passing-by-value-then-move instead. Example(AntoherType v): field(move(v)) {} // good, no copy }; auto readSomeone(Book &&book) {} // bad, use const Book &. No need moving there!
- Only the result of the compilation of
* .cpp
files in thesrc/main
folder is included in the release assembly. - The
src/main
folder contains the*.cpp
and*.h
project files together. - The
src/test
folder contains the*.cpp
and*.h
project test files together. - Each
*.h
file must define only one entity in the global namespace, whose name must match the file name. - The contents of
*.cpp
files not declared in*.h
file must be protected fromexternal linkage
from others compilation units by adding them to the anonymous namespace or adding the keywordstatic
.