Skip to content

CMake setup

Introduction

CMake is an open-source, cross-platform build system generator. It helps developers manage the build process of software projects by generating platform-specific build files (such as Makefiles or Visual Studio project files) from simple configuration files (CMakeLists.txt). CMake simplifies the process of compiling, testing, and packaging code, especially when working with multiple platforms and compilers.

Why and How to Use CMake:

  • Why use CMake?

    CMake is particularly useful for managing complex projects that need to be built on different operating systems and environments. It abstracts away the complexities of platform-specific build tools, allowing you to focus on writing code rather than worrying about compatibility. It’s widely used in both open-source and commercial software development. * How to use CMake? 1. Write a CMakeLists.txt file: This file contains instructions on how to build your project, including specifying dependencies, compiler options, source files, and installation rules. 1. Run CMake to generate build files: Use CMake to generate the appropriate build files for your system (e.g., Makefiles for Linux or Visual Studio project files for Windows). 1. Build the project: After generating the build files, you can use the platform’s build tool (e.g., make on Linux or MSBuild on Windows) to compile the project. Note: CMake ‘knows’ which build tool to use and can help you using the right commands (e.g. cmake --build or cmake --install).

Further Documentation:

For more detailed instructions and examples, you can refer to the official CMake documentation:

Following are instructions for setting up CMake for both a Python project and a C++ project.

Setting up CMake for a Python Project

CMake can be used in Python projects, typically when you’re building C extensions or wrapping C/C++ code for Python. Here’s how you can set it up for a Python project that includes C extensions:

  1. Project Structure

    python_project/
    ├── CMakeLists.txt
    ├── setup.py
    ├── src/
    │   └── example.c
    └── tests/
        └── test_example.py
    
  2. CMakeLists.txt

    Here’s an example CMakeLists.txt that builds a C extension for Python:

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.10)
    
    # Set the project name and version
    project(PythonCExample VERSION 1.0)
    
    # Find Python package and development libraries
    find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
    
    # Specify the Python module name
    set(PYTHON_MODULE_NAME example)
    
    # Add the source files (C code)
    add_library(${PYTHON_MODULE_NAME} MODULE src/example.c)
    
    # Set the include directories
    target_include_directories(${PYTHON_MODULE_NAME} PRIVATE ${Python3_INCLUDE_DIRS})
    
    # Link the necessary libraries
    target_link_libraries(${PYTHON_MODULE_NAME} PRIVATE ${Python3_LIBRARIES})
    
    # Set the module suffix (e.g., .so on Linux, .pyd on Windows)
    set_target_properties(${PYTHON_MODULE_NAME} PROPERTIES
    PREFIX ""
    SUFFIX ".${Python3_EXT_SUFFIX}"
    )
    
    # Install the Python module
    install(TARGETS ${PYTHON_MODULE_NAME} DESTINATION ${Python3_SITE_PACKAGES})
    
  3. setup.py

    In the setup.py file, you can integrate CMake as follows:

    setup.py
    from setuptools import setup, Extension
    from setuptools.command.build_ext import build_ext
    import subprocess
    import os
    
    class CMakeBuild(build_ext):
        def run(self):
            subprocess.check_call(['cmake', '.'])
            subprocess.check_call(['cmake', '--build', '.'])
            super().run()
    
    setup(
        name="python_c_example",
        version="1.0",
        ext_modules=[Extension('example', sources=[])],
        cmdclass={'build_ext': CMakeBuild},
    )
    
  4. Build and Install the Python Module

    To build and install the C extension, follow these steps:

    # Create a build directory
    mkdir build
    cd build
    
    # Run CMake to configure the project
    cmake ..
    
    # Build the project
    cmake --build .
    
    # Install the module
    python setup.py install
    
  5. Running the Tests

    After installation, you can use the Python extension as follows:

    import example
    # Run tests or use the C extension
    

Setting up CMake for a C++ Project

For C++ projects, CMake is widely used for managing the build process. Below is an example of how to set up a simple C++ project with CMake.

  1. Project Structure

    cpp_project/
    ├── CMakeLists.txt
    ├── src/
    │   ├── main.cpp
    │   └── example.cpp
    ├── include/
    │   └── example.h
    └── tests/
        └── test_example.cpp
    
  2. CMakeLists.txt

    Here’s an example CMakeLists.txt for a basic C++ project:

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.10)
    
    # Set the project name and version
    project(CppExample VERSION 1.0)
    
    # Specify C++ standard
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # Add the executable and specify the source files
    add_executable(cpp_example src/main.cpp src/example.cpp)
    
    # Optionally link external libraries (e.g., pthread)
    # target_link_libraries(cpp_example pthread)
    
    # Enable testing (if you have tests)
    enable_testing()
    add_subdirectory(tests)
    
  3. Sample C++ Source Files

    • src/main.cpp:

      src/main.cpp
      #include <iostream>
      #include "example.h"
      
      int main() {
          std::cout << "Hello from C++ project!" << std::endl;
          exampleFunction();
          return 0;
      }
      
    • src/example.cpp:

      src/example.cpp
      #include "example.h"
      
      void exampleFunction() {
          std::cout << "This is an example function." << std::endl;
      }
      
    • include/example.h:

      include/example.h
      #ifndef EXAMPLE_H
      #define EXAMPLE_H
      
      void exampleFunction();
      
      #endif // EXAMPLE_H
      
  4. Test Setup (Optional)

    If you want to include tests, you can create a simple test file in tests/test_example.cpp. * tests/test_example.cpp:

    ``` cpp title="tests/test_example.cpp"
    #include <gtest/gtest.h>
    #include "../src/example.h"
    
    TEST(ExampleTest, TestExampleFunction) {
        testing::internal::CaptureStdout();
        exampleFunction();
        std::string output = testing::internal::GetCapturedStdout();
        EXPECT_EQ(output, "This is an example function.\n");
    }
    ```
    
  5. Running Tests

    To include Google Test in your project, modify your CMakeLists.txt to fetch and link Google Test.

    CMakeLists.txt
    # Include Google Test
    include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
    
    # Add the test executable
    add_executable(test_example tests/test_example.cpp)
    
    # Link Google Test
    target_link_libraries(test_example gtest gtest_main)
    
    # Add test to CTest
    add_test(NAME test_example COMMAND test_example)
    

    You can run the tests as follows:

    # Create build directory
    mkdir build
    cd build
    
    # Configure the project
    cmake ..
    
    # Build the project
    cmake --build .
    
    # Run the tests
    ctest
    
  6. Build and Install

    Once you’ve set up your project, you can build and install it with the following commands:

    # Create a build directory
    mkdir build
    cd build
    
    # Configure the project with CMake
    cmake ..
    
    # Build the project
    cmake --build .
    
    # Optionally, install the project
    sudo cmake --install .
    

Summary

  • For Python: CMake can be used to compile C extensions that are part of the Python project, often paired with setup.py for installation.
  • For C++: CMake is used to manage the build process for compiling source code, linking libraries, and optionally running tests.