Project

General

Profile

Using CMake » History » Revision 9

Revision 8 (Charles Brockman, 07/08/2012 10:49 PM) → Revision 9/10 (Charles Brockman, 07/11/2012 04:41 AM)

h1. Using CMake 

 {{toc}} 

 In this example we are going to see how to use CMake to compile a very simple Wt project where you have a *source* directory with all your files and a *build* directory to generate your application. 

 If you don't care where your files are located or you are looking for an even simpler example, go to [[Frequently_Asked_Questions#Q-How-do-I-build-my-newly-written-Hello-World-application]]. 

 h2. 


 h4. Directory Structure 

  

 Before starting, make sure that your project main directory (In this example the main directory is called main) looks like this: 

 <pre> 
 main 
 | 
 +--source..................you have all your files here 
     | 
     + -- CMakeLists.txt .. a text file where we will write CMake commands (empty)  
 +--build.................. build directory (initially, this directory is empty) 
 +--CMakeLists.txt ........ a text file where we will write CMake commands (empty) 
 </pre> 

 h2. 


 h4. CMakeLists.txt in the Main Directory 

 main directory  

 These are the contents of the CMakeLists.txt file that you should write on the main directory: 

 <pre> 
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 

 PROJECT(WT_EXAMPLE) 

 SET (WT_CONNECTOR "wtfcgi" CACHE STRING "Connector used (wthttp or wtfcgi)") 

 ADD_SUBDIRECTORY(source) 
 </pre> 

 * The first two instructions are self descriptive. CMAKE_MINIMUM_REQUIRED checks that you have the indicated version. If you don't include this instruction in your CMakeLists.txt you will be able to continue but you will see a warning message. The second option, PROJECT, simply assigns a name to your CMake project. 

 * The third instruction is a bit more interesting. SET allows you to create variables inside a CMake script. In this case we are creating a variable named WT_CONNECTOR. It will contain a string value that, by default, will be "wtfcgi". The syntax used here is: 

 <pre> 
 SET(VARIABLE_NAME default_value CACHE type "help message") 
 </pre> 

 * The CACHE options allow us to save the value. The next time you run CMake (as you will see later), the variable will contain the last value that you entered. 

 * The last instruction in this CMake script is ADD_SUBDIRECTORY. This instruction will delegate the execution of the script to the subdirectory enclosed in parenthesis.  

 The syntax is: 

 <pre> ADD_SUBDIRECTORY(subdir)</pre> 

 Make sure that there is a CMakeLists.txt file in the subdirectory that you are referencing, so that sub CMakeLists.txt will be executed. 

 In our example, as we have one subdirectory (source), we will have a corresponding CMakeLists.txt file in there. 

 h2. h4. CMakeLists.txt in the Source Directory 

 source directory  

 This is an example of the CMakeLists.txt file that goes in the source directory: 

 <pre> 
 SET(WT_PROJECT_SOURCE 
 File1.h 
 File1.cpp 
 File2.h 
 File2.cpp 
 Main.C 
 ) 

 SET(WT_PROJECT_TARGET wt_project.wt) 

 ADD_EXECUTABLE(${WT_PROJECT_TARGET} ${WT_PROJECT_SOURCE}) 

 TARGET_LINK_LIBRARIES(${WT_PROJECT_TARGET} ${WT_CONNECTOR} wt) 

 INCLUDE_DIRECTORIES(/usr/local/include/Wt) 
 </pre> 

 Let's break this down: 

 h3. h5. Variables in a CMake Script 

 script  

 WT_PROJECT_SOURCE and WT_PROJECT_TARGET are two variables and you can change the names as you like as long as you make sure that you change them everywhere in your script. 

 h3. h5. SET Instruction 

 instruction  

 The CMake SET instruction allows us to associate any number of strings with a CMake variable. The syntax is: 

 <pre> 
 SET(CMAKE_VARIABLE string1 string2 ... stringN) 
 </pre> 

 In our example we have two SET instructions. The first one allows us to associate all our source file names with WT_PROJECT_SOURCE. The second SET instruction associates the string wt_project.wt with WT_PROJECT_TARGET. 

 h3. h5. ADD_EXECUTABLE Instruction 

 instruction  

 The ADD_EXECUTABLE instruction configures the executable file you are about to compile. The syntax is: 

 <pre> 
 ADD_EXECUTABLE(EXECUTABLE_NAME file1 file2 ... fileN) 
 </pre> 

 However given that we have our source list in the variable WT_PROJECT_SOURCE, we can write: 

 <pre> 
 ADD_EXECUTABLE(EXECUTABLE_NAME ${WT_PROJECT_SOURCE}) 
 </pre> 

 In this case, we see the way CMake variables can be used. Every time that you want to refer to any variable contents, just use the ${} syntax around the variable name. 

 h3. h5. TARGET_LINK_LIBRARIES Instruction 

 instruction  

 The TARGET_LINK_LIBRARIES instruction allows us to link our executable file with the dependent libraries. The syntax is: 
 <pre> 
 TARGET_LINK_LIBRARIES(EXECUTABLE_NAME lib1 lib2 ... libN) 
 </pre> 

 In our case we need to make sure that the our executable links to Wt (wt library) and one of the connectors (wthttp library or wtfcgi library). In our example, the connector name is stored in the variable WT_CONNECTOR. 

 h3. h5. INCLUDE_DIRECTORIES Instruction instruction  

 The INCLUDE_DIRECTORIES instruction adds the given directories to those searched by the compiler for include files. The syntax is: 
 <pre> 
 INCLUDE_DIRECTORIES(dir1 dir2 ... dirN) 
 </pre> 

 For the sake of the example, I have added the directory /usr/local/include/Wt. This is where all the Wt header files live in my Ubuntu installation. However this might not be the case for you and you might want to decipher where these files are in your system. The general solution for this is to use  

 TODO: Talk about FIND_PACKAGE 

 h2. h4. Project files/Makefiles Generation generation  

 Once you are finished editing the source/CMakeLists.txt file, go to the build directory and type: 
 <pre>cmake ..</pre> 

 You will see the initial CMake screen on your terminal console: 

 <pre> 
 <pre> 
                                                      Page 0 of 1 
  EMPTY CACHE 
 </pre> 

 


 EMPTY CACHE: 
 Press [enter] to edit option                           CMake Version 2.6 - patch 4 
 Press [c] to configure 
 Press [h] for help           Press [q] to quit without generating 
 Press [t] to toggle advanced mode (Currently Off) 
 </pre> 

 Here you need to run the configuration option by pressing *[c]* 

 This will take you to the next screen: 

 <pre> 
 <pre> 
                                                      Page 1 of 1 
  CMAKE_BUILD_TYPE                                                          
  CMAKE_INSTALL_PREFIX               /usr/local                                    
  WT_CONNECTOR                       wtfcgi                                        
 </pre> 

 CMAKE_BUILD_TYPE: Choose the type of build, options are: None(CMAKE_CXX_FLAGS or 
 Press [enter] to edit option                           CMake Version 2.6 - patch 4 
 Press [c] to configure 
 Press [h] for help           Press [q] to quit without generating 
 Press [t] to toggle advanced mode (Currently Off) 
 </pre> 

 At this point, define the type of build (CMAKE_BUILD_TYPE) you are going to do. Options are: 

 * Debug 
 * Release 
 * RelWithDebInfo 
 * MinSizeRel 

 Next we see that the variable WT_CONNECTOR that was defined in the main directory CMakeLists.txt file appears. As stated before, options for this variable are: 

 * wthttp (Wt connector) 
 * wtfcgi (FastCGI connector) 

 Once you have set these properties (for instance, selecting Debug and wtfcgi respectively), configure again by pressing *c*.    This time an additional option *g* appears:  

 <pre> 
 <pre> 
                                                      Page 1 of 1 
  CMAKE_BUILD_TYPE                   Debug                                         
  CMAKE_INSTALL_PREFIX               /usr/local                                    
  WT_CONNECTOR                       wtfcgi                                        
 </pre> 

 CMAKE_BUILD_TYPE: Choose the type of build, options are: None(CMAKE_CXX_FLAGS or 
 Press [enter] to edit option                           CMake Version 2.6 - patch 4 
 Press [c] to configure       Press [g] to generate and exit 
 Press [h] for help           Press [q] to quit without generating 
 Press [t] to toggle advanced mode (Currently Off) 
 </pre> 

 At this point you press [g] to generate your project. This step takes care of the files that need to be generated in order to compile your project on your platform. For example, if you were working on Visual Studio under Windows, then the project and solution files would be generated. On Linux, you will see that there is a set of Makefiles that you will use to compile your project. 

 After pressing [g] you will end up in the build directory again. This time we just do a regular *make*. The output should be something similar to this: 
 cg 
 <pre> 
 make 
 [ 50%] Building CXX object src/CMakeFiles/App.wt.dir/App.cpp.o 
 [100%] Building CXX object src/CMakeFiles/App.wt.dir/Main.C.o 
 Linking CXX executable App.wt 
 [100%] Built target App.wt 
 </pre> 

 Now your application is ready to go. To execute your application, follow the guidelines for the case where you are using the built-in Wt server or any FastCGI supporting web server. 

 h2. h4. Summary 

 Well that is basically it. I hope this had been helpful to understand a little bit more what CMake is about. As this is the first version of this document please feel free to make any comments, suggestion, or corrections. 

 If you want to learn more about the different instructions that CMake offers I advise you to visit: 

 * Pau Garcia's CMake slides (http://www.elpauer.org/stuff/learning_cmake.pdf) 
 * The CMake documentation webpage (http://www.cmake.org/cmake/help/cmake2.6docs.html) 
 * CMake with Eclipse (http://www.cmake.org/Wiki/CMake:Eclipse_UNIX_Tutorial)