A very exciting feature in C++Builder 10.2.3 is support for using CMake with our compilers. Let’s dig in!
This post is the first in a series on CMake, and will cover:
- What CMake is
- How to write a CMakeLists.txt file
- How to build a project on Windows
Table of Contents
What is CMake?
You can think of CMake as a platform-independent, compiler-independent, project format for C++ apps and libraries.
CMake uses a file called CMakeLists.txt. This is a plain text, human-editable, description of a project: the files that need to be built, the project name(s), dependencies, etc. Here’s an example:
. cmake_minimum_required (VERSION 3.10) project (MyProjectName) add_executable(MyProjectName one.cpp two.cpp three.cpp)
This says:
- This file works with CMake 3.10 (that’s ten not one) or higher
- There is a project called MyProjectName
- And to build MyProjectName.exe, build one.cpp, two.cpp, and three.cpp
This is a simple example. A CMakeLists.txt file is more akin to the project group in C++Builder than a project, because it can specify several projects, dependencies among them, etc.
This is completely compiler-independent. CMake knows how to build the above project as well with cc on Solaris as gcc on Linux as clang on Mac. Naturally, sometimes you do need to set vendor- or platform-specific settings, and you can do that as well. We do, for example to specify linking against the VCL or FMX runtime, which is very specific to C++Builder, or to link with the dynamic runtime, which has equivalents for other compilers but is still specific to us in implementation.
CMake has good documentation, but I think it’s a bit opaque if you don’t already know CMake. Personally, I recommend reading Jeff Pershing’s blog series on CMake: How to Build a CMake-Based Project and Learn CMake’s Scripting Language in 15 Minutes. There’s a wealth of well-explained material there that will make you a CMake expert in no time.
Advantages of CMake Support for C++Builder
Many third-party open source C++ libraries come packaged as CMake projects. In the past, to use these you’d have to create a C++Builder project for them, which is manual work. Now, you can just build them on the command line right away.
This makes it significantly easier for you to use other common libraries in your projects.
One secondary item is that we support using Ninja with CMake. This allows parallel building. We already support parallel compilation in C++Builder, but I’ll cover Ninja in a followup blog post.
What have we added?
We have added: Support for using CMake to build with all of C++Builder’s Clang-based command-line compilers: for Win32, Win64, iOS32, iOS64, and Android.
(You could already use CMake with the classic compiler.)
Using CMake for Windows
Installation
- Download and install CMake. When installing, make sure you choose the option to add CMake to the system path. If you don’t, you’ll have to specify the full path the CMake each time you want to use it.
- Optionally, but highly recommended, download Ninja. This is a plain EXE: place it somewhere on your system and add that location to the system path manually.
- Install C++Builder 10.2.3 🙂
- There is one very important installation step. Do not miss this or you will get strange error messages. We have updated the Windows-Embarcadero.cmake file compared to the version currently shipped with CMake. So, open
C:\Program Files (x86)\Embarcadero\Studio\19.0\cmake
And copy and paste Windows-Embarcadero.cmake to:
C:\Program Files\CMake\share\cmake-3.11\Modules\Platform
(3.11 is the CMake version.) Back the file up first.
If you do not do this final step, you will get a rather puzzling error message when running CMake, something like:
. -- Check for working C compiler: C:/Program Files (x86)/Embarcadero/Studio/19.0/bin/bcc64.exe -- broken CMake Error at C:/Program Files/CMake/share/cmake-3.11/Modules/CMakeTestCCompiler.cmake:52 (message): The C compiler "C:/Program Files (x86)/Embarcadero/Studio/19.0/bin/bcc64.exe" is not able to compile a simple test program. It fails with the following output: [ -- Long compiler command line omitted -- ] error: invalid integral value 'd' in '-Od' CMake will not be able to correctly generate this project.
If you see this, copy over Windows-Embarcadero.cmake as above. We hope that soon, perhaps 10.3, we will be able to support CMake out of the box without needing to ship an updated configuration file.
Example Windows CMakeLists.txt
Above, I showed a very simple CMakeLists.txt to demonstrate the concept. Let’s look at one for a real project. This is for a FireMonkey Windows application I built for CodeRage last year.
. cmake_minimum_required (VERSION 3.10) project (Mazes) set_embt_target("FMX" "DynamicRuntime") add_executable(Mazes CppMazes.cpp Algorithms.cpp Cell.cpp DistanceDijkstra.cpp Grid.cpp MainForm.cpp)
Looks very similar, doesn’t it? There is one addition: an Embarcadero-specific line, set_embt_target. This macro specifies whether to link with the VCL or FMX, the dynamic runtime, or as a package. These can be combined and are listed in our documentation.
If you are building a VCL application, just write,
. set_embt_target(VCL)
Which does not link against the dynamic runtime (because it was not specified) but does link against the VCL.
In normal CMake projects, you need to specify WIN32 in the add_executable call, which specifies that it is not a console app (ie sets a PE flag and uses WinMain.) If you specify the VCL or FMX, you don’t need to do this; we automatically do. You can override it and specify console if you need.
Want to find more – how to build a shared library, or a package, or…? We have six sample CMakeLists.txt files in our documentation.
Building for Windows
All the above is just background – all you really need to know is here, two command lines!
You have CMake installed and you have a CMakeLists.txt file. Building is very straightforward: call cmake, specifying that you want to use bcc64 or bcc32x as the C and C++ compiler. That’s it. CMake automatically looks for the CMakeLists.txt file, and based on the compiler you specify knows if it’s Win32 or Win64.
For example,
. cmake -DCMAKE_C_COMPILER=bcc32x.exe -DCMAKE_CXX_COMPILER=bcc32x.exe -G Ninja
or,
. cmake -DCMAKE_C_COMPILER=bcc64.exe -DCMAKE_CXX_COMPILER=bcc64.exe -G Ninja
This will run CMake and use the Ninja generator, that is, generate the files that Ninja needs to build. More on Ninja or using other generators in another post. This process only need to be run once; you can run it again to update when your project changes, such as adding a new file. You do not need to run it every time to build, just once.
To build, call ninja:
. ninja
That’s it. Simple! You will see ninja build for a short while, and find the executable in your base folder.
Using CMake for iOS and Android
More info about targeting iOS and Android in the next post, tomorrow!
Overview
Using CMake is actually really simple. Install it, make sure there is a CMakeLists.txt file, and call cmake. Thereafter, build with a single word: ninja.
This lets you build third party C++ libraries easily: download and run cmake. Or, you can build your own projects if you write a CMakeLists.txt file. Not only does this make it really easy to use other C++ libraries or code, but there are other benefits to using generators like ninja too (speed, for example.) Compatibility and being able to integrate well with the wider C++ world is very important to us, making it easy for you to use libraries and code from elsewhere, and easy for people to use C++Builder. We’re very excited to support CMake — and have much more to tell you!
- More info about targeting iOS and Android in the next post!
- More on Ninja, next week!
Don’t forget to read what else is new in 10.2.3.