Hi, I am very new to CMake. In fact, I am trying this tutorial http://www.cmake.org/cmake-tutorial/. I do not understand some of the words prescribe there but I can manage. The problem I have with tutorials is the inclusion of TutorialConfig.h. I check the tutorial files and such file doesn't exist. Here are the tutorial files for each step: http://public.kitware.com/cgi-bin/viewcvs.cgi/CMake/Tests/Tutorial/. I am stuck at (step 1). I don't really understand the #include "TutorialConfig.h" but it ask me to write a "TutorialConfig.h.in" which contain definitions for major and minor version numbers. Including that file manually, my compiler spits out an error saying it is an unrecognized token. Does it really matter?

The main point I am tinkering with CMake is that I wanted to create a simple class "SimpleClassA" with a function that prints out "Hello World" and I wanted this to become a x-platform, IDE/Technology independent library. I want my SimpleClassA to have a respective .dll/.so. I have known on my research that .obj files generated during compilation are being passed onto the linker (which translates the .obj files to a .exe/.o or .dll/.so. Now if I could just get the .obj file of SimpleClassA and turn it to a .dll, that be great. I am using CMake to build couple of libraries like SFML, SFGUI etc. etc. I noticed that these libraries are x-platform and uses Cmake and decided maybe this is the path I need and decided I wanted to try similar effort.

Having said all this, I am stuck at Step 1. Any help will be appreciated.

So, from the link you gave, there are three files in there, and they are short enough that I'll simply post them here:

CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")

# add the executable
add_executable(Tutorial tutorial.cxx)

TutorialConfig.h.in:

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

tutorial.cxx: (should be tutorial.c, because this is C, not C++)

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"

int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n",
            argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

The most important line that needs explanation is the following line from the CMakeLists.txt file:

configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )

The configure_file command in CMake will take some input file (in this case, "TutorialConfig.h.in") and generate an output file (in this case, "TutorialConfig.h") which will be the same as the input file but every occurrence of @Something@ (where "Something" can be anything) will be replaced by the CMake variable of the same name (the "Something").

So, in the TutorialConfig.h.in file, there is this line:

#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@

which means that when CMake generates the TutorialConfig.h file, it will replace the @Tutorial_VERSION_MAJOR@ with the value of the CMake variable called Tutorial_VERSION_MAJOR. That variable is set a couple of lines earlier in the CMake file, by this command:

set (Tutorial_VERSION_MAJOR 1)

which means that its value is just "1", and therefore, in the output file "TutorialConfig.h" generated by CMake, you will get this resulting line:

#define Tutorial_VERSION_MAJOR 1

And the same goes for the minor version. In other words, the configure_file is just a "find-and-replace" utility that can be used for things like this, when you want to take the values of CMake variable and put them into source / header files (or other files too).

One last thing that might be confusing is the path of the input and output files:

  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"

The ${PROJECT_SOURCE_DIR} evaluates the CMake variable PROJECT_SOURCE_DIR which is a built-in CMake variable that contains the full path to the source directory in which the project() command was emitted from (i.e., your top-level CMakeLists.txt file). This means that the input file path "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" will point to the "TutorialConfig.h.in" file in the top-level source directory, as included in the files in the link you gave.

For the output file, the path is now in PROJECT_BINARY_DIR which is contains the full path to the "binary" directory. This directory is actually the directory from which you called CMake (and then "make"). When you use cmake through the command-line, you would typically do what is called an "out-of-source build", which means that you create a separate folder for compiling the project (to keep the source folder clean). When you use cmake through an IDE, this folder might be created for you. But all this doesn't matter too much. The point is that the actual file "TutorialConfig.h" is only used when compiling the code, and that's why it gets generated into that "binary" folder, away from the source folder. And, to make sure that this generated header file can be found during the compilation of the source file, there is this cmake command in the CMakeLists.txt file:

include_directories("${PROJECT_BINARY_DIR}")

which adds the PROJECT_BINARY_DIR path to the include directories (where the compiler looks for files when there is a #include command).

If you take those three files, unmodified, and try to build the CMake project, it should work. It certainly worked for me. If not, there might be a problem in the way you invoke CMake itself, or how you make the build.

the inclusion of TutorialConfig.h. I check the tutorial files and such file doesn't exist.

The file does not exist until you run CMake on the project. This is a file that CMake generates from the TutorialConfig.h.in file.

I noticed that these libraries are x-platform and uses Cmake and decided maybe this is the path I need and decided I wanted to try similar effort.

That's a good decision. CMake is pretty much an industry standard build tool at this point. The only projects that I know of that don't use it wish they were using it, and are seriously talking about migrating to CMake. There is definitely a bit of learning involved, but it's really not that hard, and it is certainly much better than any other build systems (make, autoconf, bjam, etc.., they are all terrible or limited or really painful to use compared to CMake).

I have known on my research that .obj files generated during compilation are being passed onto the linker ...

You might want to read my article on "Understanding C++ from sources to binaries". It's very important to understand how all of this works (it will help you tremendously when working out compilation and linking problems), and it's really not that complicated once you understand the basic rules of how it works.

This article has been dead for over six months. Start a new discussion instead.