Using CMake with C++ Builder

From RAD Studio
Jump to: navigation, search

CMake Command-Line Support

RAD Studio includes support for building CMake projects on the command line using RAD Studio's C++ Compilers. You can compile for Windows or for other platforms from Windows. CMake supports RAD Studio’s Clang-enhanced compilers: BCC64 for 64-bit Windows and BCC32X for 32-bit Windows. RAD Studio also supports using Ninja with CMake. This allows for fast parallel compilation.

Installing CMake and Ninja

CMake

Download and install CMake 3.19.4. Use the binary installer, since it can optionally add CMake to the system path. Make sure you select that option during the installation.

CMake files are located in C:\Program Files (x86)\Embarcadero\Studio\23.0\cmake. However, to prevent errors in the build process, you need to move one file manually. Follow the steps below to do this:

  1. Locate your CMake installation folder and the Modules\Platform subfolder. E.g. C:\Program Files\CMake\Modules\Platform
  2. Locate the Windows-Embarcadero.cmake file and make a backup.
  3. Copy Windows-Embarcadero.cmake from the Studio\23.0\cmake\Modules folder and overwrite the version in the CMake Modules directory.

We have greatly extended the inbuilt CMake support for the Windows compilers and you need to use this file to build successfully.

Ninja

Download and install Ninja. You will need to add it to the system path manually.

How to use CMake

CMake builds based on a text file called CMakeLists.txt that tells CMake which files to build. You can find more information in their developer documentation. We also recommend Jeff Preshing’s blog series on CMake: How to Build a CMake-based Project and Learn CMake’s Scripting Language in 15 Minutes.

To use CMake, you need the following files:

  • C++ source you want to build: Many C++ files and headers.
  • CMakeLists.txt file: Defines the project name, tells it to find all source files, and builds them in one executable, library, package, etc. See below for several sample files. More advanced CMakeLists.txt files specify several projects.
  • (Optionally) Batch script to drive CMake: Use the batch script (*.bat) to contain several commands. CMake can create a large number of files, and you can use the batch file to create a subfolder where all output including CMake’s files are placed. This blog post on using bcc32c with CMake has more details.
Run the batch script from the command line to generate the executable file along with many other files in the specified subfolder.
Note: Store the CMakeLists.txt file in the root folder of your project. You can store the source files in a subfolder.

Incremental Links

FromRAD StudioSidney 10.4, you should not have any issues related to incremental links when using CMake + Ninja to build a static library.

For older versions, if the dependency information is not generated during the build, set the CMAKE_DEPFILE_FLAGS_CXX variable in CMakeLists.txt as it follows:

For clang compilers:

set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <OBJECT> -MF <DEPFILE>"

For the classic compiler:

set(CMAKE_DEPFILE_FLAGS_CXX "-md -mo\"<DEPFILE>\"")
Note: When the headers change and nothing is compiled or recompiled, we say that the dependency information is not generated.

Building using CMake

Start a RAD Studio command prompt from the Start menu, or by opening a command prompt and executing rsvars.bat in the RAD Studio \bin folder.

CMake looks for a CMakeLists.txt file. See below for information on creating one of these for a project.

Targeting Windows

To target Win32: cmake -DCMAKE_C_COMPILER=bcc32x.exe -DCMAKE_CXX_COMPILER=bcc32x.exe -G Ninja <directory> [1]

To target Win64: cmake -DCMAKE_C_COMPILER=bcc64.exe -DCMAKE_CXX_COMPILER=bcc64.exe -G Ninja <directory> [1]

Then, ninja

To invoke Ninja to do the actual build.

Warning: Since the Win64 projects use 32bit file extensions, you might have issues by building Win64 applications via CMake. To avoid them, copy the tree under the Modules node to the CMake Modules directory. Remember to copy the files of the Platforms and the Compiler subdirectories.

Other command-line flags

  • -G”Borland Makefiles” to use old-fashioned make to build.
  • -DCMAKE_BUILD_TYPE_INIT=Release to target debug or release builds.
  • -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON for easier to debug output.
  • --debug-output to put CMake in debug mode.

For example:

cmake -DCMAKE_C_COMPILER=bcc32x.exe -DCMAKE_CXX_COMPILER=bcc32x.exe -DCMAKE_BUILD_TYPE_INIT=Release -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -G "Borland Makefiles" --debug-output -v ..

To use the Win32 compiler, release build, some verbose and debugging flags, and build using make, with CMakeLists.txt located in the parent folder.

C++ Builder-specific support in a CMakeLists.txt

Targets

Using CMake, you can create executables, DLLs, static libraries, and packages.

 set_embt_target(FMX)
 set_embt_target(VCL)
 set_embt_target(Package)
 set_embt_target(DynamicRuntime)

Or combinations:

 set_embt_target(VCL DynamicRuntime)

Macros and variables

There are a number of macros and variables for Windows. This sample CMakeLists.txt shows several of them:

 cmake_minimum_required(VERSION 3.9)
 set(APP "FMXApp")
 set(CMAKE_BUILD_TYPE "DEBUG")
 set(EMBT_PROJECT_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/Project_${APP}")
 project (${APP})
 
 # Create a sources variable with a link to all cpp files to compile
 file(GLOB SOURCES
     "src/*.h"
     "src/*.cpp"
 )
 set_embt_target("FMX")
 if(EMBT_TARGET STREQUAL Windows)
     add_executable (${APP} WIN32 ${SOURCES})
     install(TARGETS ${APP} RUNTIME DESTINATION bin)
 else()
     add_fmx_app("${SOURCES}")
 endif()

Manifests

To add a Manifest, you must create a resource file that includes:

#pragma code_page(65001)
124 "name.manifest"

Also, you can post-process with the Windows SDK tool manifest mt.exe:

add_custom_command(
 TARGET ${PROJECT_NAME}
 POST_BUILD
 COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.manifest\" -outputresource:\"$<TARGET_FILE:${PROJECT_NAME}>\")
Attention: Building with CMake uses an RTL link by default.

Example CMakeLists.txt file

For a project called Example, with source files in the same folder, a very minimal CMakeLists.txt file is:

 cmake_minimum_required (VERSION 3.10)
 project (Example)
 
 file(GLOB Example_SRC
    "*.h"
    "*.cpp"
 )
 
 add_executable(Example ${Example_SRC})

This specifies the minimum version (3.10); the project name; that it uses all available .cpp and .h files, and compiles them all into Example.exe.

“Glob”-ing all files together is quick and easy, but is not a recommended best practice; instead, it is better to specify the files you want to use. You can specify .cpp files and headers, but one minimal example specifying .cpp files is:

 cmake_minimum_required (VERSION 3.10)
 project (Example)
 
 add_executable(Example main.cpp foo.cpp bar.cpp)

Sample CMakeLists.txt: VCL app

cmake_minimum_required(VERSION 3.9)
 project (VCLApp)
 set_embt_target(VCL DynamicRuntime)
 add_executable (VCLApp WIN32 src/VCLApplication.cpp src/Project1.cpp)
 install(TARGETS VCLApp
             RUNTIME DESTINATION bin
             LIBRARY DESTINATION lib
             ARCHIVE DESTINATION lib/static
 )

Sample CMakeLists.txt: FMX app

cmake_minimum_required(VERSION 3.9)
 project (FMXApp)
 set_embt_target(FMX)
 add_executable (FMXApp WIN32 src/FMXSample.cpp src/FMXProj.cpp)
 install(TARGETS FMXApp RUNTIME DESTINATION bin)

Sample CMakeLists.txt: shared library

project(SharedLibrary)
 
 set(SharedLibrary_headers SharedLibrary.h)
 set(SharedLibrary_sources SharedLibrary.cpp)
 
 add_library(SharedLibrary SHARED SharedLibrary.h SharedLibrary.cpp)
 
 install(TARGETS     SharedLibrary 
                     RUNTIME DESTINATION bin
                     LIBRARY DESTINATION lib
                     ARCHIVE DESTINATION lib/static
        )

Sample CMakeLists.txt: Static Library

project(StaticLibrary)
 
 set(StaticLibrary_headers StaticLibrary.h)
 set(StaticLibrary_sources StaticLibrary.cpp)
 
 add_library(StaticLibrary STATIC StaticLibrary.h StaticLibrary.cpp)
 install(TARGETS     StaticLibrary
                     RUNTIME DESTINATION bin
                     LIBRARY DESTINATION lib
                     ARCHIVE DESTINATION lib/static
        )

Sample CMakeLists.txt: Package

cmake_minimum_required(VERSION 3.9)
 
 project (PackageExample)
 set_embt_target(Package)
 add_library(PackageExample SHARED PackageExample.cpp)
 
 install(TARGETS     PackageExample
                     RUNTIME DESTINATION bin
                     LIBRARY DESTINATION lib
                     ARCHIVE DESTINATION lib/static
        )

Sample CMakeLists.txt: Resources

cmake_minimum_required(VERSION 3.9)
 
 project (myapp)
 set(SYSTEM_SOURCES ${SYSTEM_SOURCES} myapp.rc ) 
 set(StrTableRes_SRCS resource.h myapp.cpp)
 ADD_EXECUTABLE(myapp WIN32 ${SYSTEM_SOURCES} ${StrTableRes_SRCS} )

See Also

  • 1.0 1.1 Directory where cmakelists.txt file is located