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:
projectNamesetting the project namedirectoriesdescribing the directory structure of the project
The following items are optional:
c++Standardsetting the standard to compile against. If missing, it defaults to 17. Possible values are: 98, 11, 14, 17, 20.compilerOptionssetting 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:
sourceindicating that it will contain implementation filesheaderindicating that it will contain header filestestindicating that it will contain unit test codeintermediateindicating 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:
libraryindicating whether a given component should be delivered as a library. Onlysourcetype directories should use this option. Its values can benull,STATICorSHARED. 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.executableindicating whether a given component should have an executable, if set totrue, amain.cppwill be generated. Onlysourcetype directories should use this option.includeindicating whether a givensourcecomponent has a correspondingincludecounterpart or not. Onlysourcetype directories should use this option.dependenciesarray 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:
typeindicating 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, onlyconanis supported.nameindicating 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)
versionis optional and has no role forinternaldependencies, but forconantype 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.