CMake Introduction - 04 - Custom Compilation Options

Posted by Zyx on Fri, 23 Aug 2019 11:57:36 +0200

work environment

  • System: macOS Mojave 10.14.6
  • CMake: Version 3.15.0-rc4

Hello,World! - Custom compilation options

CMake allows you to add compilation options to your project, so that you can choose the most appropriate compilation solution based on the user's environment and needs.

For example, you can set the MathFunctions library as an optional library, and if the option is ON, you can use the mathematical functions defined by the library to perform operations. Otherwise, call the mathematical function library in the standard library.

(0) Initialization project

$ mkdir hello
$ cd hello
$ mkdir math build
$ touch CMakeLists.txt main.cpp math/MathFunctions.h math/MathFunctions.cpp math/CMakeLists.txt
$ tree
.
├── build
├── CMakeLists.txt
├── main.cpp
└── math
    ├── CMakeLists.txt
    ├── MathFunctions.cpp
    └── MathFunctions.h
  • math/MathFunctions.h
int power(int base, int exponent);
  • math/MathFunctions.cpp
#include <stdio.h>
#include <stdlib.h>
#include "MathFunctions.h"

int power(int base, int exponent) {
    int result = base;
    int i;

    if (exponent == 0) {
        return 1;
    }

    for(i = 1; i < exponent; ++i){
        result = result * base;
    }
    return result;
}
  • main.cpp
#include <iostream>
#include "MathFunctions.h"

using namespace std;

int main(int argc, char const *argv[]) {
  printf("%s power(2,3)=%d \n", "Hello,World!", power(2, 3));
  return 0;
}
  • CMakeLists.txt
# CMake Minimum Version Number Requirements
cmake_minimum_required(VERSION 3.15.0)

# Project name
project(hello)

# Find all source files in the current directory and save the name to the SRC_LIST variable
aux_source_directory(. SRC_LIST)
# Find all source files in the math directory and save the name to the MATH_SRC_LIST variable
# aux_source_directory(${PROJECT_SOURCE_DIR}/math MATH_SRC_LIST)

# Add the math subdirectory (the math directory must have CMakeLists.txt), so that the CMakeLists.txt files and source code under the math directory will also be processed.
add_subdirectory(math)

# Add header file path
include_directories(${PROJECT_SOURCE_DIR}/math)

# Specify a build target
add_executable(hello ${SRC_LIST} ${MATH_SRC_LIST})

# Add Link Library
target_link_libraries(hello MathFunctions)
  • math/CMakeLists.txt
# Find all source files in the current directory and save the name to the DIR_LIB_SRCS variable
aux_source_directory(. DIR_LIB_SRCS)

# Generating Link Library
add_library (MathFunctions ${DIR_LIB_SRCS})

(1) Modify the root directory CMakeLists.txt

cmake_minimum_required(VERSION 3.15.0)

# Project name
project(hello)

# Find all source files in the current directory and save the name to the SRC_LIST variable
aux_source_directory(. SRC_LIST)


# Add a configuration header file to handle CMake source settings
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_SOURCE_DIR}/config.h"
)

# Whether to use your own MathFunctions Library
# The variable USE_MYMATH, the prompt text in the middle, and the default value set here are displayed in the ccmake command.
option (USE_MYMATH
  "Use provided math implementation"
  ON
)

# Whether to join the MathFunctions library or not
if (USE_MYMATH)
  # Add header file path
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  # Add the math subdirectory (the math directory must have CMakeLists.txt)
  add_subdirectory (math)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)



# Specify a build target
add_executable(hello ${SRC_LIST} ${MATH_SRC_LIST})

# Add Link Library
target_link_libraries(hello ${EXTRA_LIBS})
  • The configure_file command is used to add a configuration header file config.h, which is generated by CMake from config.h.in. Through this mechanism, code generation can be controlled by predefining some parameters and variables.
  • The option command adds a USE_MYMATH option and the default value is ON.
  • The value of the USE_MYMATH variable determines whether to use our own MathFunctions library.

(2) Modify the main.cpp file

#include <iostream>
#include "config.h"

#ifdef USE_MYMATH
  // If USE_MYMATH is defined, import "MathFunctions.h"
  #include "MathFunctions.h"
#else
  // If USE_MYMATH is not defined, import <cmath>
  #include <cmath>
#endif

using namespace std;

int main(int argc, char const *argv[]) {

  #ifdef USE_MYMATH
    printf("Here define USE_MYMATH \n");
    printf("%s power(2,3)=%d \n", "Hello,World!", power(2, 3));
  #else
    printf("Here undefine USE_MYMATH \n");
    printf("%s power(2,3)=%f \n", "Hello,World!", pow(2, 3));
  #endif

  return 0;
}

(3) New config.h.in file

#cmakedefine USE_MYMATH
  • In this way, CMake automatically generates config.h files according to the config.h.in configuration file settings.

(4) Compiling & Running

  • cmake command compilation
$ cd Desktop/hello/build

# cmake specifies USE_MYMATH=ON
$ cmake -DUSE_MYMATH=ON ..
-- The C compiler identification is AppleClang 10.0.1.10010046
-- The CXX compiler identification is AppleClang 10.0.1.10010046
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/staff/Desktop/hello/build

$  make
Scanning dependencies of target MathFunctions
[ 25%] Building CXX object math/CMakeFiles/MathFunctions.dir/MathFunctions.cpp.o
[ 50%] Linking CXX static library libMathFunctions.a
[ 50%] Built target MathFunctions
Scanning dependencies of target hello
[ 75%] Building CXX object CMakeFiles/hello.dir/main.cpp.o
[100%] Linking CXX executable hello
[100%] Built target hello

# Here define USE_MYMATH“
$ ./hello
Here define USE_MYMATH
Hello,World! power(2,3)=8

# cmake specifies USE_MYMATH=OFF
$ cmake -DUSE_MYMATH=OFF ..
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/staff/Desktop/hello/build

$ make
Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles/hello.dir/main.cpp.o
[100%] Linking CXX executable hello
[100%] Built target hello

# Here undefine USE_MYMATH output“
$ ./hello
Here undefine USE_MYMATH
Hello,World! power(2,3)=8.000000
  • ccmake command compilation
$ cd Desktop/hello/build
$ ccmake ..

You can see the USE_MATH option

  • Keyboard direction keys can be switched between different options
  • Press enter to modify this option
  • After the modification is completed, you can press the c option to complete the configuration, and then press the g key to confirm the generation of Makefile.
  • Other operations of ccmake can refer to instructions given below the window.

Relevant references:
CMake official website
CMake Initial Practice

Contact author:

Topics: C++ cmake xcode Makefile