Aside from C++ I'm also picking up a new build tool; CMake. CMake is certainly not a new tool, but this is the first time I've had to use it, and I thought I would share what I've learned about it so far. As part of the learning process I have created a "Hello, World!" application using CMake, which I've made available at GitHub at https://github.com/jameskbride/cmake-hello-world . This extremely simple application does exactly what you would expect, which is spitting out "Hello, world!" to command line, but it was a great opportunity to explore CMake. So, lets get to it and dive into the CMake world!
Project Root CMakeLists.txt
CMake is primarily configured via 'CMakeLists.txt', which lives in the root of the project, as well as the root of every sub-project. Lets take a look at the CMakeLists.txt file in the root of this project shall we?cmake_minimum_required (VERSION 2.8) project (CMakeHelloWorld) #version number set (CMakeHelloWorld_VERSION_MAJOR 1) set (CMakeHelloWorld_VERSION_MINOR 0) #include the subdirectory containing our libs add_subdirectory (Hello) #indicate the entry point for the executable add_executable (CMakeHelloWorld Hello HelloWorld.cpp) # Indicate which libraries to include during the link process. target_link_libraries (CMakeHelloWorld Hello) install (TARGETS CMakeHelloWorld DESTINATION bin)
As you can see this is a simple text file which contains CMake specific commands. The first interesting bit here is line 2, which indicates the project name.:
project (CMakeHelloWorld)Line 9 tells CMake where to find the header and .cpp files for the subproject.
add_subdirectory (Hello)
Line 12 indicates where the executable go resides, as well as the entry point for the application (HelloWorld.cpp).
add_executable (CMakeHelloWorld Hello HelloWorld.cpp)
I probably did not have to have the entry point in the root directory of the project, but I thought it would clearly separate it from the library code if I placed it there. Line 15 tells the linker which projects to use when wiring up the compiled units.
target_link_libraries (CMakeHelloWorld Hello)
Finally, line 17 tells CMake where to install the target project binaries.
install (TARGETS CMakeHelloWorld DESTINATION bin)
Subproject (Hello) CMakeLists.txt
In order to modularize the code I created a subdirectory which contains the Speaker.h and Speaker.cpp source files, which contain the logic for the class which actually produces the "Hello, World!" output. Here is the CMakeLists.txt file for that subproject:add_library (Hello Speaker.h Speaker.cpp) install (TARGETS Hello DESTINATION bin) install (FILES Speaker.h DESTINATION include)Again, this is pretty straightforward. First we declare we are adding a library, "Hello", followed by a listing of the .h and .cpp files to be included as part of the build. We then define an install target for the subproject (Note: this does *not* create a new executable binary as part of the build.). Finally we define the list of header files to be included during the build.
Building the Project
During my first attempt to use CMake followed the instructions I found in various blogs which stated that I should simply go to the root of the project and executecmake . && make && make installWhile this does build the project it has the undesirable effect of splattering build gore all over the walls of your project. Your directories will be littered with generated directories and files which you otherwise wouldn't care about. Luckily, the solution is simple. CMake allows you to point to where your CMakeLists.txt files live (the "cmake ." piece of the previous command). As such, creating a build directory, changing to it and executing
cmakewill execute the build and cause the resulting output to be dumped into your cleanly encapsulated build directory.&& make && make install
The build will now generate an executable file, CMakeHelloWorld, which can be called using the standard "./CMakeHelloWorld" command.
You now know as much as I currently know about CMake, so go forth and make! There will be more of these types of posts in the future, so I hope you found this informative and I hope you'll come back. For more detail be sure to check out the GitHub repo, and please feel free to leave feedback. Thanks!
Oh goodness me, who said time travel was not possible :) Good work Jim, I enjoyed it!
ReplyDeleteThanks Boyko! It's interesting, CMake has been around for a while but it definitely still in use. Stick around, I plan to do more of these.
ReplyDelete