From: Matthias Maier Date: Thu, 12 Sep 2013 10:01:28 +0000 (+0000) Subject: Doc: Some progress wrt. the CMake documentation X-Git-Tag: v8.1.0~825 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=105bf34358cfc76689c7d1bb3ddd64c857807582;p=dealii.git Doc: Some progress wrt. the CMake documentation git-svn-id: https://svn.dealii.org/trunk@30677 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/doc/development/cmake.html b/deal.II/doc/development/cmake.html index 86c663bfb9..208e2617b7 100644 --- a/deal.II/doc/development/cmake.html +++ b/deal.II/doc/development/cmake.html @@ -419,15 +419,17 @@ you may receive an error message of the form:

-CMake Warning at source/CMakeLists.txt:65 (ADD_LIBRARY):
-  Cannot generate a safe runtime search path for target deal_II.g because
-  files in some directories may conflict with libraries in implicit
-  directories:
 
-    runtime library [libtbb.so.2] in /usr/lib may be hidden by files in:
-      /my/private/lib
+    CMake Warning at source/CMakeLists.txt:65 (ADD_LIBRARY):
+      Cannot generate a safe runtime search path for target deal_II.g because
+      files in some directories may conflict with libraries in implicit
+      directories:
+
+        runtime library [libtbb.so.2] in /usr/lib may be hidden by files in:
+          /my/private/lib
+
+      Some of these libraries may not be found correctly.
 
-  Some of these libraries may not be found correctly.
 

This is not a problem of CMake or deal.II, but rather a general diff --git a/deal.II/doc/development/cmakelists.html b/deal.II/doc/development/cmakelists.html index 44fb38ae3f..fe34b34891 100644 --- a/deal.II/doc/development/cmakelists.html +++ b/deal.II/doc/development/cmakelists.html @@ -10,7 +10,7 @@ - +

How to use CMake to configure your projects with deal.II

@@ -20,6 +20,7 @@
  1. Adding multiple executable targets
  2. Adding libraries and common source files
  3. +
  4. Switching build types
  5. Adding a "run" target
@@ -58,16 +59,14 @@

Simple CMakeLists.txt

- In this section, we start out with a - minimal CMakeLists.txt based on - the DEAL_II_SETUP_TARGET macro. This method gives - full control of what's happening and is easily extensible to - more complex projects, as exemplified in the subsections here an - later in the section on advanced - topics. Here is a full example + In this section, we start out with a minimal CMakeLists.txt + based on the DEAL_II_SETUP_TARGET macro. This method gives + full control of what's happening and is easily extensible to more complex + projects, as exemplified in the subsections here and later in the section + on advanced topics. Here is a full example (plain text version): - +

Fix plain text after finalizing!

@@ -75,10 +74,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
 
 FIND_PACKAGE(deal.II 8.0 REQUIRED
   HINTS ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR}
-)
+  )
 DEAL_II_INITIALIZE_CACHED_VARIABLES()
 
-PROJECT(myproject CXX)
+PROJECT(myproject)
 
 ADD_EXECUTABLE(mycode mycode.cc)
 DEAL_II_SETUP_TARGET(mycode)
@@ -92,33 +91,42 @@ DEAL_II_SETUP_TARGET(mycode)
 

- Next, we find our deal.II installation, in this case requiring at - least version 8.0, which is the first version using - CMake. The HINTS are a list of directories where the - install directory of deal.II is likely to be found. Here, we check - whether we are in a subdirectory (first and second level) of the - deal.II installation and otherwise use the - variable DEAL_II_DIR. - Matthias, what is the difference between the first - and the last entry? This list can be changed according to your - preferences. After finding the deal.II project, we fetch its chached - variables. You can inspect these for instance - with ccmake. + Next, we find our deal.II installation with the help of the + FIND_PACKAGE command. In this case requiring at least + version 8.0, which is the first version using CMake. The + HINTS are a list of directories where the install directory + of deal.II is likely to be found. First, the location possibly defined in + the CMake variable DEAL_II_DIR is considered. After that, we + check whether we are in a subdirectory (first and second level) of the + deal.II installation and otherwise use the environment variable + DEAL_II_DIR. If all of these hints fail the default system + locations /usr/ and /usr/local/ are considered. + The list after HINTS can be changed according to your + preferences.

- Every CMAkeLists.txt must contain a project definition, - which we do next. Matthias, I have been happy - without the CXX...? + After finding the deal.II project, we fetch a set of cached variables + with the DEAL_II_INITIALIZE_CACHED_VARIABLES() macro. You + can inspect these for instance with ccmake. +

+ +

link to detailed explanation of the macro below

+ +

+ Every CMakeLists.txt must contain a project definition, + which we do next.

Finally, the last two lines define the executable that is to be - produced and its source code. + produced and its source code. The DEAL_II_SETUP_TARGET macro + will set up necessary incllude directories, compile defintions and the + link interface.

-

Explain the macros or link to explanation below

+

link to detailed explanation of the macro below

Adding multiple executable targets

@@ -152,6 +160,7 @@ with GLOB.
 ADD_LIBRARY(mylib libsrc1.cc libsrc2.cc libsrc3.cc)
+DEAL_II_SETUP_TARGET(mylib)
 
 ADD_EXECUTABLE(mycode mycode.cc)
 DEAL_II_SETUP_TARGET(mycode)
@@ -174,85 +183,214 @@ ADD_EXECUTABLE(mycode2 mycode2.cc common.cc)
 DEAL_II_SETUP_TARGET(mycode2)
 
-

You should be aware though that common.cc will be -compiled for each target, not only once.

+

You should be aware though that in this case common.cc will +be compiled for each target, not only once. If you want to avoid this and +still don't want to use a shared library or static archive, another option +is to create an OBJECT "library":

+ +
+ADD_LIBRARY(common OBJECT common.cc)
+DEAL_II_SETUP_TARGET(common)
 
-

Matthias, is this correct?

+ADD_EXECUTABLE(mycode mycode.cc $<TARGET_OBJECTS:common>) +DEAL_II_SETUP_TARGET(mycode) +ADD_EXECUTABLE(mycode2 mycode2.cc $<TARGET_OBJECTS:common>) +DEAL_II_SETUP_TARGET(mycode2) +
+This will compile common.cc once for the object target +common and link the resulting object file into the two +executables. + + +

Switching build types

+ +

The build type is controlled via the variable +CMAKE_BUILD_TYPE. If it is set to Debug +executables and libraries specified in your CMakeLists.txt +file will be compiled in debug mode and linked against the debug version of +the deal.II library. Contrary Release will build in optimized +mode and link against the optimized release version of deal.II. You can set +CMAKE_BUILD_TYPE with the help of ccmake or via +cmake on the command line:

- -

Adding a "run" target

- -

- If you wish to have a "run" target for make, like in the deal.II - tutorial, specify one this way (obviously, a single "run" target - can only run a single executable): -

+
+$ cmake -DCMAKE_BUILD_TYPE="Debug" .
+
+$ cmake -DCMAKE_BUILD_TYPE="Release" .
+
+ +Alternatively, you can specify custom targets to switch the build type and +compile automatically: + +
+ADD_CUSTOM_TARGET(debug
+  COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR}
+  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
+  COMMENT "Switch CMAKE_BUILD_TYPE to Debug"
+  )
+
+ADD_CUSTOM_TARGET(release
+  COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR}
+  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
+  COMMENT "Switch CMAKE_BUILD_TYPE to Release"
+  )
+
+With that, switching the build type and compiling the project can be done +very conveniently via: +
+$ make debug
+
+$ make release
+
+ + +

Adding a "run" target

+ +

If you wish to have a "run" target for make, like in the deal.II +tutorial, specify one this way (obviously, a single "run" target can only +run a single executable):

 ADD_CUSTOM_TARGET(run COMMAND mycode
-  COMMENT "Run with ${CMAKE_BUILD_TYPE} configuration")
+  COMMENT "Run with ${CMAKE_BUILD_TYPE} configuration"
+  )
 

Advanced CMakeLists.txt

-
-  
-  A Subsection for each of the following:
-  
-  - control statements (if and foreach)
-  
-  - file glob to pick up sources
-  
-  - DEAL_II_SETUP_TARGET and DEAL_II_INITIALIZE_CACHED_VARIABLES
-  revisited
-  
-  - add include dirs and compile definitions to a directory or target
-  
-  - provide a ./run folder and target
-  
-  - custom targets to switch between release and debug
-  
-  - installation
+

This section covers some advanced topics for a user +CMakeLIists.txt file.

+ + +

Control statements

+ +

Control statements in CMake take the following form: +

+IF(<expression>)
+  ...
+ENDIF()
+
+or in long form: +
+IF(<expression1>)
+  ...
+ELSEIF(<expression2>)
+  ...
+ELSE()
+  ...
+ENDIF()
+
+Please note the (somehow uncommon) empty, opening and closing brackets +behind ELSE() and ENDIF(). +<expression> can take a multitude of different forms, +have a look at the +CMake +documentation for a complete list. Important examples are: +

Link!

+
+IF(${variable})
+  - the body will be evaluated if the variable "variable" is defined and
+    synonymous to true, e.g. 1, TRUE, ON, YES (modulo case insensitivity)
+
+IF(variable MATCHES <regular expression>)
+  - the body will be evaluated if the variable "variable" is defined and
+    matches the specified regular expression
+
+IF("${variable}" STREQUAL "foobar")
+  - the body will be evaluated if both strings are equal. Note that
+    "${variable}" will be replaced by the content of the (string)
+    variable "variable"
+
+

An expression can be negated by prefixing NOT:

+
+IF(NOT <expression>)
+  ...
+ENDIF()
 
- -

Finding the deal.II library

+

Loops are implemented with the help of WHILE and +FOR statements. The former takes the same +<expression> as the IF statement:

+
+WHILE(<expression>)
+  ...
+ENDWHILE()
+
+Given a variable list containing a list, the individual +elements element can be accessed with a FOREACH +statement: +
+FOREACH(element ${list})
+  ...
+ENDFOREACH
+
+Note: It is also possible to specify the list directly: +
+FOREACH(element foo bar baz)
+  # The variable element will iterate through foo, bar and baz.
+ENDFOREACH
+
-

- Finding the deal.II library should be no more than -

-    
-    FIND_PACKAGE(deal.II REQUIRED)
-  
- in your CMakeLists.txt file. You may have to hint for the location - of the deal.IIConfig.cmake file. Either by directly - specifying deal.II_DIR to point to the path were the - deal.IIConfig.cmake file is located: - -

is deal.II_DIR still accurate? We use different -above. BTW, that is an UGLY variable name.

- -
    
-cmake -Ddeal.II_DIR=/path/to/the/config/file <...>
 
+
+

File globs

+ +

A very common task is to pick up a list of source files from a +directory. You can either manage a list of source files in +CMakeLists.txt by hand, e.g. by manually updating all source +files for a given target, or you can use a glob to automate this process. +The following example will pick up every source file under +SOURCE_DIR/sources/ and add it to an executable:

+ +
+FILE(GLOB sources ${CMAKE_SOURCE_DIR}/source/*.cc)
+ADD_EXECUTABLE(mycode ${sources})
 
- or by specifying a search path via CMAKE_PREFIX_PATH, - e.g. -
-    
-    cmake -DCMAKE_PREFIX_PATH=~/workspace/local
-  
- In this case deal.IIConfig.cmake will be searched - for in -
-    
-    ~/workspace/local/
-    ~/workspace/local/lib/cmake/deal.II/
-  
-

+ +

Please be aware of one caveat of this approach: Due to the fact that +CMake is a build system generator the resulting build configuration +(for make) has no way to detect whether a new source file was added (or +removed) and that it has to call back to cmake. So, after adding a new +source file you have to touch a CMakeLists.txt file or to run +cmake . again by hand. + + + +

DEAL_II_SETUP_TARGET revisited

+ +

Well, write this!

+ + + +

DEAL_II_INITIALIZE_CACHED_VARIABLES revisited

+ +

Well, write this!

+ + + +

Customizing include directories and compile definitions

+ +

Well, write this!

+ + + +

External libraries

+ +

Well, write this!

+ + + +

The "run" target revisited

+ +

Well, write this!

+ + + +

Install a project

+

Autopilot style CMakeLists.txt