1
0
mirror of synced 2024-12-22 20:50:00 +01:00

Adding nice examples

This commit is contained in:
Henry Fredrick Schreiner 2018-03-29 13:26:47 +02:00
parent cf824ab47c
commit 8861642e5c
13 changed files with 80 additions and 24 deletions

View File

@ -4,6 +4,8 @@
* [Installing CMake](chapters/installing.md) * [Installing CMake](chapters/installing.md)
* [Running CMake](chapters/running.md) * [Running CMake](chapters/running.md)
---
## Making a CMakeLists ## Making a CMakeLists
* [Introduction to the Basics](chapters/basics.md) * [Introduction to the Basics](chapters/basics.md)
@ -20,9 +22,14 @@
* [Debugging (X)](chapters/debug.md) * [Debugging (X)](chapters/debug.md)
* [Exporting and Installing](chapters/exporting.md) * [Exporting and Installing](chapters/exporting.md)
---
## Specific packages ## Specific packages
* [CUDA](specifics/CUDA.md) * [CUDA](specifics/CUDA.md)
* [OpenMP](specifics/OpenMP.md) * [OpenMP](specifics/OpenMP.md)
* [Boost (X)](specifics/Boost.md) * [Boost (X)](specifics/Boost.md)
* [MPI](specifics/MPI.md) * [MPI](specifics/MPI.md)
* [ROOT (INCOMPLETE)](specifics/ROOT.md) * [ROOT](specifics/ROOT.md)
* [Simple Example](examples/root-simple/README.md)
* [Simple Example CMake 3.11+](examples/root-simple-3.11/README.md)
* [Dictionary Example](examples/root-dict/README.md)

View File

@ -2,7 +2,7 @@
"title": "Modern CMake", "title": "Modern CMake",
"description": "A guide to writing simple, powerful, and clean CMake 3.1+ builds.", "description": "A guide to writing simple, powerful, and clean CMake 3.1+ builds.",
"author": "Henry Schreiner", "author": "Henry Schreiner",
"plugins": ["hints","term","include-codeblock"], "plugins": ["collapsible-menu", "hints", "term", "include-codeblock"],
"pluginsConfig": { "pluginsConfig": {
"include-codeblock": { "include-codeblock": {
"fixlang": true "fixlang": true

View File

@ -3,4 +3,3 @@
Double_t Simple::GetX() const {return x;} Double_t Simple::GetX() const {return x;}
ClassImp(Simple) ClassImp(Simple)

View File

@ -10,5 +10,4 @@ public:
Double_t GetX() const; Double_t GetX() const;
ClassDef(Simple,1) ClassDef(Simple,1)
}; };

View File

@ -1,13 +1,11 @@
// See: https://root.cern.ch/selecting-dictionary-entries-linkdefh // See: https://root.cern.ch/selecting-dictionary-entries-linkdefh
#ifdef __CINT__ #ifdef __CINT__
#pragma link off all globals; #pragma link off all globals;
#pragma link off all classes; #pragma link off all classes;
#pragma link off all functions; #pragma link off all functions;
#pragma link C++ nestedclasses; #pragma link C++ nestedclasses;
#pragma link C++ class Simple+; #pragma link C++ class Simple+;
#endif #endif

View File

@ -0,0 +1,28 @@
# Dictionary Example
This is an example of building a module that includes a dictionary in CMake.
#### examples/root-dict/CMakeLists.txt
[import:'main', lang:'cmake'](CMakeLists.txt)
## Supporting files
This is just a simple-as-possible class definition, with one method:
#### examples/root-dict/DictExample.cxx
[import, lang:'c_cpp'](DictExample.cxx)
#### examples/root-dict/DictExample.h
[import, lang:'c_cpp'](DictExample.h)
We need a `LinkDef.h`, as well.
#### examples/root-dict/DictLinkDef.h
[import, lang:'c_cpp'](DictLinkDef.h)
## Testing it
This is an example of a macro that tests the correct generation from the files listed above.
#### examples/root-dict/CheckLoad.C
[import, lang:'c_cpp'](CheckLoad.C)

View File

@ -1,3 +1,5 @@
## [main]
cmake_minimum_required(VERSION 3.11) cmake_minimum_required(VERSION 3.11)
project(RootSimpleExample311 LANGUAGES CXX) project(RootSimpleExample311 LANGUAGES CXX)
@ -14,6 +16,7 @@ target_compile_options(ROOT::Core INTERFACE "${ROOT_CXX_FLAG_LIST}")
add_executable(RootSimpleExample311 SimpleExample.cxx) add_executable(RootSimpleExample311 SimpleExample.cxx)
target_link_libraries(RootSimpleExample311 PUBLIC ROOT::Physics) target_link_libraries(RootSimpleExample311 PUBLIC ROOT::Physics)
## [main]
enable_testing() enable_testing()
add_test(NAME RootSimpleExample311 COMMAND RootSimpleExample311) add_test(NAME RootSimpleExample311 COMMAND RootSimpleExample311)

View File

@ -0,0 +1,11 @@
# A Simple ROOT Project (CMake 3.11)
This is a minimal example of a ROOT project using the target system and without a dictionary.
This uses the new support in CMake 3.11+ for adding interface properties on an imported interface target.
#### examples/root-simple-3.11/CMakeLists.txt
[import:'main', lang:'cmake'](CMakeLists.txt)
#### examples/root-simple-3.11/SimpleExample.cxx
[import](SimpleExample.cxx)

View File

@ -1,5 +1,5 @@
#include <TLorentzVector.h> #include <TLorentzVector.h>
int main() { int main() {
TLorentzVector v(1,2,3,4); TLorentzVector v(1,2,3,4);
v.Print(); v.Print();

View File

@ -21,6 +21,7 @@ set_property(TARGET ROOT::Core APPEND PROPERTY
INTERFACE_COMPILE_OPTIONS ${ROOT_CXX_FLAG_LIST}) INTERFACE_COMPILE_OPTIONS ${ROOT_CXX_FLAG_LIST})
## [setup_properties] ## [setup_properties]
# Adding an exectuable program and linking to needed ROOT libraries
## [add_and_link] ## [add_and_link]
add_executable(RootSimpleExample SimpleExample.cxx) add_executable(RootSimpleExample SimpleExample.cxx)
target_link_libraries(RootSimpleExample PUBLIC ROOT::Physics) target_link_libraries(RootSimpleExample PUBLIC ROOT::Physics)

View File

@ -0,0 +1,10 @@
# A Simple ROOT Project
This is a minimal example of a ROOT project using the target system and without a dictionary.
#### examples/root-simple/CMakeLists.txt
[import:'main', lang:'cmake'](CMakeLists.txt)
#### examples/root-simple/SimpleExample.cxx
[import](SimpleExample.cxx)

View File

@ -1,5 +1,5 @@
#include <TLorentzVector.h> #include <TLorentzVector.h>
int main() { int main() {
TLorentzVector v(1,2,3,4); TLorentzVector v(1,2,3,4);
v.Print(); v.Print();

View File

@ -7,7 +7,7 @@ ROOT is a C++ Toolkit for High Energy Physics. It is huge. There are really a lo
ROOT supports config file discovery, so you can just do: ROOT supports config file discovery, so you can just do:
[import:'find_package', lang:'cmake'](../examples/root-example/CMakeLists.txt) [import:'find_package', lang:'cmake'](../examples/root-simple/CMakeLists.txt)
to attempt to find ROOT. If you don't have your paths set up, you can pass `-DROOT_DIR=$ROOTSYS/cmake` to find ROOT. (But, really, you should source `thisroot.sh`) to attempt to find ROOT. If you don't have your paths set up, you can pass `-DROOT_DIR=$ROOTSYS/cmake` to find ROOT. (But, really, you should source `thisroot.sh`)
@ -19,20 +19,18 @@ ROOT provides a utility to set up a ROOT project, which you can activate using `
ROOT does not correctly set up it's imported targets. To fix this error, you'll need something like: ROOT does not correctly set up it's imported targets. To fix this error, you'll need something like:
[import:'setup_properties', lang:'cmake'](../examples/root-example/CMakeLists.txt) [import:'setup_properties', lang:'cmake'](../examples/root-simple/CMakeLists.txt)
In CMake 3.11, you can replace that last function call with: In CMake 3.11, you can replace that last function call with:
```cmake
target_include_directories(ROOT::Core IMPORTED INTERFACE "${ROOT_INCLUDE_DIRS}") [import:'modern_fix', lang:'cmake'](../examples/root-simple-3.11/CMakeLists.txt)
target_compile_options(ROOT::Core IMPORTED INTERFACE "${ROOT_CXX_FLAG_LIST}")
```
All the ROOT targets will require `ROOT::Core`, so this will be enough regardless of which ROOT targets you need. All the ROOT targets will require `ROOT::Core`, so this will be enough regardless of which ROOT targets you need.
To link, just pick the libraries you want to use: To link, just pick the libraries you want to use:
[import:'add_and_link', lang:'cmake'](../examples/root-example/CMakeLists.txt) [import:'add_and_link', lang:'cmake'](../examples/root-simple/CMakeLists.txt)
## Dictionary generation ## Dictionary generation
@ -42,7 +40,7 @@ Dictionary generation is ROOT's way of working around the missing reflection fea
* Your class implementation should have `ClassImp(MyClassName)` in it * Your class implementation should have `ClassImp(MyClassName)` in it
* You should have a file with a name that ends with `LinkDef.h` * You should have a file with a name that ends with `LinkDef.h`
The `LinkDef.h` file follows a specific formula and tells ROOT what parts to generate dictionaries for. The `LinkDef.h` file follows a [specific formula][linkdef-root] and tells ROOT what parts to generate dictionaries for.
To generate, you should include the following in your CMakeLists: To generate, you should include the following in your CMakeLists:
@ -50,20 +48,22 @@ To generate, you should include the following in your CMakeLists:
include("${ROOT_DIR}/modules/RootNewMacros.cmake") include("${ROOT_DIR}/modules/RootNewMacros.cmake")
include_directories(ROOT_BUG) include_directories(ROOT_BUG)
``` ```
The second line is due to a bug in the NewMacros file that causes dictionary generation to fail if there is not at least one global include directory or a `inc` folder. Here I'm including a non-existent directory just to make it work. There is no `ROOT_BUG` directory. The second line is due to a bug in the NewMacros file that causes dictionary generation to fail if there is not at least one global include directory or a `inc` folder. Here I'm including a non-existent directory just to make it work. There is no `ROOT_BUG` directory.
To generate a file: To generate a file:
```cmake ```cmake
root_generate_dictionary(G__MyExample MyExample.h LINKDEF SimpleLinkDef.h) root_generate_dictionary(G__Example Example.h LINKDEF ExampleLinkDef.h)
``` ```
Then include `G__MyExample.cxx` in your sources when you make the library. The final argument, listed after `LINKDEF`, must have a name that ends in `LinkDef.h`. This command will create three files. If you started output name with `G__`, that will be removed from the name, otherwise it will use the name given; this must match the final output library name you will soon be creating. Assuming this is `${NAME}`:
## Example: Minimal * `${NAME}.cxx`: This file should be included in your sources when you make the library.
* `lib{NAME}.rootmap` (`G__` prefix removed): The rootmap file in plain text
* `lib{NAME}_rdict.pcm` (`G__` prefix removed): A ROOT file
#### examples/root-example/CMakeLists.txt The final two output files must sit next to the library output. This is done by checking `CMAKE_LIBRARY_OUTPUT_DIRECTORY` (it will not pick up local target settings). If you have a libdir set but you don't have (global) install locations set, you'll also need to set `ARG_NOINSTALL` to `TRUE`.
[import:'main', lang:'cmake'](../examples/root-example/CMakeLists.txt)
[linkdef-root]: https://root.cern.ch/selecting-dictionary-entries-linkdefh
## Example: Dictionary
[import:'main', lang:'cmake', title:"CMakeLists.txt"](../examples/root-example-dict/CMakeLists.txt)