Setting Up the Initial CMake for my TVM project

·

3 min read

CMake is a powerful tool used for managing the build process in C++ projects. It’s designed to be cross-platform, allowing you to easily configure and build your project on multiple operating systems.

This blog shows the initial CMake configuration for my TVM from scratch project. It walks through the setup of a simple CMakeLists.txt file, and explain it step by step.

Why Use CMake?

CMake is highly flexible and widely used in the C++ community. It abstracts away many details of the build system, making it easier to manage large projects, link external libraries, and handle platform-specific configurations. By using CMake, you’re setting up your project in a standardized way that many other C++ developers will recognize.

Setting Up a Basic CMakeLists.txt File

Project Directory Structure

Before we dive into the CMakeLists.txt file, let’s think about the project structure. For now, we may just have the following

MyTVM/
├── src/
├── include/
├── 3rdparty/
├── CMakeLists.txt
└── README.md
  • src/: This directory contains the C++ source files.

  • CMakeLists.txt: This file is where we’ll configure CMake to build our project.

Writing the CMakeLists.txt File

cmake_minimal_required(VERSION 3.31)
project(MyTVM)

First we define the minimum CMake version at the top of the file. This ensures compatibility and helps avoid issues on older CMake versions.

Then we define the project name as MyTVM.

# Set C++ standard
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

Next we specify the C++ standard.

  • CMAKE_CXX_STANDARD: This sets the C++ standard to C++14.

  • CMAKE_CXX_STANDARD_REQUIRED: Ensures that the C++ standard we set is strictly enforced.

  • CMAKE_CXX_EXTENSIONS: Disables compiler-specific extensions, which can improve cross-platform compatibility.

# Add subdirectories
add_subdirectory(src)

CMake’s add_subdirectory function allows us to modularize the project. Each subdirectory can have its own CMakeLists.txt, making it easier to manage large codebases. For now, we’ll just include the src/ directory.

option(USE_DEBUG "Enable debugging symbols" OFF)
if(USE_DEBUG)
    set(CMAKE_BUILD_TYPE Debug)
else()
    set(CMAKE_BUILD_TYPE Release)
endif()

This part configures the debug options. Sometimes we want to build the project with debugging symbols (for development) or optimizations (for release). CMake allows us to define options that developers can toggle.

  • USE_DEBUG: A toggle for enabling debugging symbols, defaulting to OFF.

  • CMAKE_BUILD_TYPE: Sets the build type to Debug or Release based on the toggle.

To build with debugging symbols, simply run: cmake -DUSE_DEBUG=ON ..

include(FetchContent)

FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG v1.15.0
)

FetchContent_MakeAvailable(googletest)

Adding Third-Party Dependencies with FetchContent:

CMake's FetchContent makes it straightforward to managing external dependencies. Instead of manually downloading and including libraries, we can fetch and configure them directly in the CMakeLists.txt. Here, we’ll add GoogleTest for unit testing.

  • FetchContent_Declare: Declares an external dependency (GoogleTest in this case) by specifying its repository and version.

  • FetchContent_MakeAvailable: Fetches and makes the dependency available for use.

Placeholder src directory

In /src directory, put the following two files as the placeholder.

# Placeholder CMakeLists.txt for the src directory
add_library(myTVM STATIC placeholder.cpp)

target_include_directories(myTVM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

This is the placeholder CMakeLists.txt

We also need a placeholder.cpp

#include <iostream>

void placeholder_function() {
    std::cout << "This is a placeholder function in myTVM!" << std::endl;
}

Building the project

To build your project using CMake, follow these steps:

  1. Create a build/ directory for out-of-source builds:

     mkdir build && cd build
    
  2. Run cmake to configure the project:

     cmake ..
    
  3. Build the project:

     make
    

Conclusion

We configured a simple CMakeLists.txt file to get started. This setup establishes a initial point for future development, where we will build our own TVM from scratch.