Cmake Project Creator helps you generate a new C++ project. Instead of writing the Cmakefiles and creating all the folders by hand, you can either
- generate a project from an already existing description
- write a new description file yourself
You need the following software installed on your laptop
Call ./create_cmake_project.py --help
to print the help message.
Briefly, you can call the project_creator
with one of the predefined options, or you can pass in your own project description.
You should also pass in the path with -o
or --output
where your new project should be generated. If it's not passed then the project will be created under the generated_projects directory.
Once a project is generated, navigate to the root of the freshly created project and call ./runTest.sh
to launch the build and the unit tests - if any. Where a test directory is defined, a failing unit test is generated.
Even though you can include any unit testing framework that is available through Conan, their won't be some default failing tests generated, unless the framework is listed in this section.
The following unit testing frameworks are supported:
You have the following predefined schemas shipped with project_creator
.
Invoke this with -d examples/single.json
. It will create a project with one include, one source and one test folder. GTest will be included for unit testing through Conan.
myProject
|_ include
|_ src
|_ test
Invoke this with -d examples/single.json
. It will create a project with one include, one source and one test folder. Catch2 will be included for unit testing through Conan.
myProject
|_ include
|_ src
|_ test
Invoke this with -d examples/single_with_compiler_options.json
. Like the single.json
, it will create a project with one include, one source and one test folder. More than that, it will define the following compiler options on a project level: -Wall -Wextra -Wpedantic -Werror
.
myProject
|_ include
|_ src
|_ test
Invoke this with -d examples/single_lib.json
. Like the single.json
, it will create a project with one include, one source and one test folder. More than that, it doesn't only deliver an executable, but it also creates a shared library.
myProject
|_ include
|_ src
|_ test
Invoke this with -d examples/single_with_boost.json
. Like the single.json
, it will create a project with one include, one source and one test folder. More than that, it includes boost
as a dependency for the source directory and gtest
for tests.
myProject
|_ include
|_ src
|_ test
Invoke the tool with -d examples/dual.json
and the following project will be generated:
myProject
|_ executable
|_ include
|_ src
|_ test
|_ library
|_ include
|_ src
|_ test
The executable
sub-directory will include library
sub-directory as a dependency and will also have a main.cpp
as such an executable. The library
is just a static library.
GTest will be included for unit testing through Conan.
Invoke the tool with -d examples/nested_dual.json
and the following project will be generated:
myProject
|_ common_root
|_ executable
|_ include
|_ src
|_ test
|_ library
|_ include
|_ src
|_ test
The executable
sub-directory will include library
sub-directory as a dependency and will also have a main.cpp
as such an executable. The library
is just a static library.
So what is the difference compared to the dual
project? Not much, it's just that the subdirectories are nested in a new common root. This is more to show you an example, how it is possible. You can check the description in examples/nested_dual.json
.
GTest will be included for unit testing with the help of Conan.
First of all, project descriptions are written in JSON format.
In the root of the JSON, you'll have to specify the projectName
attribute, which will be used both for the directory name where the project will be created and evidently it will be the name of the Cmake project.
Then you have to specify an array of directories
.
There are two mandatory elements:
projectName
setting the project namedirectories
describing the directory structure of the project
The following items are optional:
c++Standard
setting the standard to compile against. If missing, it defaults to 17. Possible values are: 98, 11, 14, 17, 20.compilerOptions
setting extra compiler options. This field takes an array of strings, for example:"compilerOptions": ["-Wall", "-Wextra", "-Wpedantic", "-Werror"]
.
Each object in the directories
must specify a name
attribute, a type
attribute and/or subdirectories.
The name
attribute defines the directory name.
The type
attribute can take the following values:
source
indicating that it will contain implementation filesheader
indicating that it will contain header filestest
indicating that it will contain unit test codeintermediate
indicating that it will only contain other subdirectories
In the subdirectories array, you can list the other directory
objects to be put nested in the given directory
.
A directory object can have the following optional elements:
library
indicating whether a given component should be delivered as a library. Onlysource
type directories should use this option. Its values can benull
,STATIC
orSHARED
. Beware that if you decide to go withnull
, you want to be able to link it in unittests. I recommend delivering a library if you want to have tests. More info on the topic here.executable
indicating whether a given component should have an executable, if set totrue
, amain.cpp
will be generated. Onlysource
type directories should use this option.include
indicating whether a givensource
component has a correspondinginclude
counterpart or not. Onlysource
type directories should use this option.dependencies
array containing all the dependencies of the given component
The dependency
object is to describe a dependency of the enclosing component. It has 2 mandatory attributes and 1 optional:
type
indicating whether the dependency is of another directory of the project (internal
) or if it's an external one. Among external ones, for the time being, onlyconan
is supported.name
indicating the name of the dependency, in case of internal ones it should be the relative path of the depended directory including the project root. (E.g.common_root/executable/library
)
version
is optional and has no role forinternal
dependencies, but forconan
type dependencies it indicates the version of the component we want to include and the format must follow the Conan syntax. You can both use specific versions or version ranges
In any case, please check the Github issues, maybe there is already an item, already a discussion concerning your idea. If that's not the case, open an issue and let's discuss it there.
In terms of coding guidelines, I follow the PEP 8 Style guide for Pyhon. Tests must be provided.