Using CMake for Project Development

Installing CMake Tool

 yum install cmake

Installing yaml-cpp

Unzipping yaml-cpp
[root@vbox ~]# unzip yaml-cpp-master.zip
Entering the Source Directory
[root@vbox ~]# cd yaml-cpp-master/
Creating Build Directory
[root@vbox yaml-cpp-master]# mkdir build && cd build
Generating Build Files
[root@vbox build]# ls
CMakeCache.txt  cmake_install.cmake    CTestTestfile.cmake    Makefile  util                   yaml-cpp-config-version.cmake
CMakeFiles      cmake_uninstall.cmake  DartConfiguration.tcl  Testing   yaml-cpp-config.cmake  yaml-cpp.pc

CMake Installation (Generating Shared Library)
[root@vbox build]# cmake -DYAML_BUILD_SHARED_LIBS=on ..
-- The CXX compiler identification is GNU 12.3.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.4s)
-- Generating done (0.1s)
-- Build files have been written to: /root/yaml-cpp-master/build
Compiling the Installation
[root@vbox build]# make
[  2%] Building CXX object CMakeFiles/yaml-cpp.dir/src/contrib/graphbuilder.cpp.o
[  5%] Building CXX object CMakeFiles/yaml-cpp.dir/src/contrib/graphbuilderadapter.cpp.o
[  7%] Building CXX object CMakeFiles/yaml-cpp.dir/src/binary.cpp.o
[ 10%] Building CXX object CMakeFiles/yaml-cpp.dir/src/convert.cpp.o
[ 12%] Building CXX object CMakeFiles/yaml-cpp.dir/src/depthguard.cpp.o
Installation (Can be Omitted)
[root@vbox build]# make install

We can simply copy the generated shared library and header files without installing them system-wide; just copy them into our project.

Shared Library

Using CMake for Project Development

Header Files

Using CMake for Project Development

Creating a C++ Project

[root@vbox include]# mkdir /root/utility_private/test_cmake
[root@vbox include]# mkdir /root/utility_private/test_cmake/include
[root@vbox include]# mkdir /root/utility_private/test_cmake/lib
Copying Header Files and Shared Library Files

Header Files

[root@vbox include]# pwd
/root/yaml-cpp-master/include
drwxr-xr-x. 4 root root 4096 Apr 30 05:53 yaml-cpp
[root@vbox include]# cp -r yaml-cpp /root/utility_private/test_cmake/include/

Shared Library

[root@vbox build]# pwd
/root/yaml-cpp-master/build
[root@vbox build]# ll
total 1764
-rw-r--r--.  1 root root   18447 Apr 30 13:41 CMakeCache.txt
drwxr-xr-x. 36 root root    4096 Apr 30 13:43 CMakeFiles
-rw-r--r--.  1 root root    5330 Apr 30 13:41 cmake_install.cmake
-rw-r--r--.  1 root root     878 Apr 30 13:41 cmake_uninstall.cmake
-rw-r--r--.  1 root root     277 Apr 30 13:41 CTestTestfile.cmake
-rw-r--r--.  1 root root    2439 Apr 30 13:41 DartConfiguration.tcl
lrwxrwxrwx.  1 root root      18 Apr 30 13:43 libyaml-cpp.so -> libyaml-cpp.so.0.8
lrwxrwxrwx.  1 root root      20 Apr 30 13:43 libyaml-cpp.so.0.8 -> libyaml-cpp.so.0.8.0
-rwxr-xr-x.  1 root root 1684096 Apr 30 13:43 libyaml-cpp.so.0.8.0
-rw-r--r--.  1 root root   50586 Apr 30 13:41 Makefile
drwxr-xr-x.  3 root root    4096 Apr 30 13:41 Testing
drwxr-xr-x.  3 root root    4096 Apr 30 13:43 util
-rw-r--r--.  1 root root    2188 Apr 30 13:41 yaml-cpp-config.cmake
-rw-r--r--.  1 root root    1861 Apr 30 13:41 yaml-cpp-config-version.cmake
-rw-r--r--.  1 root root     235 Apr 30 13:41 yaml-cpp.pc
[root@vbox build]# cp libyaml-cpp.so libyaml-cpp.so.0.8 libyaml-cpp.so.0.8.0 /root/utility_private/test_cmake/lib/

Handling Symbolic Link Issues

[root@vbox lib]# rm libyaml-cpp.so libyaml-cpp.so.0.8
rm: remove regular file 'libyaml-cpp.so'? y
rm: remove regular file 'libyaml-cpp.so.0.8'? y
[root@vbox lib]# ll
total 1648
-rwxr-xr-x. 1 root root 1684096 Apr 30 14:00 libyaml-cpp.so.0.8.0
[root@vbox lib]# ln -s libyaml-cpp.so.0.8.0 libyaml-cpp.so.0.8
[root@vbox lib]# ll
total 1648
lrwxrwxrwx. 1 root root      20 Apr 30 14:02 libyaml-cpp.so.0.8 -> libyaml-cpp.so.0.8.0
-rwxr-xr-x. 1 root root 1684096 Apr 30 14:00 libyaml-cpp.so.0.8.0
[root@vbox lib]# ln -s libyaml-cpp.so.0.8.0 libyaml-cpp.so
[root@vbox lib]# ll
total 1648
lrwxrwxrwx. 1 root root      20 Apr 30 14:02 libyaml-cpp.so -> libyaml-cpp.so.0.8.0
lrwxrwxrwx. 1 root root      20 Apr 30 14:02 libyaml-cpp.so.0.8 -> libyaml-cpp.so.0.8.0
-rwxr-xr-x. 1 root root 1684096 Apr 30 14:00 libyaml-cpp.so.0.8.0
[root@vbox lib]#
Project Structure
[root@vbox test_cmake]# tree -L 2
.
├── CMakeLists.txt
├── include
│   └── yaml-cpp
├── lib
│   ├── libyaml-cpp.so -> libyaml-cpp.so.0.8.0
│   ├── libyaml-cpp.so.0.8 -> libyaml-cpp.so.0.8.0
│   └── libyaml-cpp.so.0.8.0
└── src
    ├── config.yaml
    └── main.cpp
Project Source Code
main.cpp
#include "yaml.h"
#include "stdio.h"
#include <string>
#include <iostream>
// #include <type_traits>
#include <sstream>

template <class T>
static inline void find(YAML::Node config, const std::string &type, T &val)
{
    if constexpr (std::is_same<T, YAML::Node>::value)
    {
        if (config.Type() != YAML::NodeType::value::Scalar && (config[type].Type() == YAML::NodeType::value::Sequence || config[type].Type() == YAML::NodeType::value::Map))
        {
            val = config[type];
            return;
        }
    }
    else
    {
        if (config.Type() != YAML::NodeType::value::Scalar && config[type].Type() == YAML::NodeType::value::Scalar)
        {
            val = config[type].as<T>();
            return;
        }
    }

    switch (config.Type())
    {
    case YAML::NodeType::value::Undefined:
    case YAML::NodeType::value::Null:
    case YAML::NodeType::value::Scalar: // scalar
    {
        break;
    }
    case YAML::NodeType::value::Sequence: // sequence
    {
        for (auto itvv : config)
        {
            find<T>(itvv, type, val);
        }
        break;
    }
    case YAML::NodeType::value::Map: // map
    {
        for (auto itvv : config)
        {
            YAML::Node nNext = itvv.second;
            find<T>(nNext, type, val);
        }
        break;
    }
    default:
        break;
    }
}

YAML::Node load(const std::string &file)
{
    printf("load %s.\n", file.c_str());

    YAML::Node config = YAML::LoadFile(file);
    if (config.Type() == YAML::NodeType::value::Undefined || config.Type() == YAML::NodeType::value::Null || config.Type() == YAML::NodeType::value::Scalar)
    {
        printf("error load %s.\n", file.c_str());
    }

    return config;
}

int main(int argc, char *argv[])
{
    YAML::Node cfg = load("./config.yaml");
    std::cout << cfg << std::endl;

    std::string Q1, Q2, Q3;
    find(cfg, "param", Q1);
    find(cfg, "Id1", Q2);
    find(cfg, "S1", Q3);
    printf("Q1:%s,Q2:%s,Q3:%s\n", Q1.c_str(), Q2.c_str(), Q3.c_str());
    return 0;
}
config.yaml
TEST:
  TEST_1:
    Info: "xxxxx.so"
    param: "hhhhhhh"
    SEN:
      Id1: "211"
    SEN:
      Id2: "277"

  TEST_2:
    CHLS:
      - {S0: "XX_S0", R0: "XX_R0"}
      - {S1: "XX_S1", R1: "XX_R1"}
      - {S2: "XX_S2", R2: "XX_R2"}
      - {S3: "XX_S3", R3: "XX_R3"}

CMakeLists.txt File

cmake_minimum_required(VERSION 3.16)
message(">>> CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
message(">>> CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
SET(CMAKE_C_FLAGS_DEBUG  "${CMAKE_C_FLAGS_DEBUG} -g ")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
#add_definitions(-std=c++11)
set(LIBNAME tYaml)
project(${LIBNAME} C CXX)
include_directories(
    ./src
    ./include
    ./include/yaml-cpp
)
set(SOURCES
    src/main.cpp
)
link_directories(
    lib
)
add_executable(${LIBNAME}  ${SOURCES})
set(LIBRARIES pthread 
yaml-cpp
)
target_link_libraries(${LIBNAME}   ${LIBRARIES})
[root@vbox test_cmake]# ls
CMakeLists.txt  include  lib  src
[root@vbox test_cmake]# mkdir build && cd build
[root@vbox build]# cmake ..
>>> CMAKE_CURRENT_SOURCE_DIR = /root/utility_private/test_cmake
>>> CMAKE_TOOLCHAIN_FILE =
-- The C compiler identification is GNU 12.3.1
-- The CXX compiler identification is GNU 12.3.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.9s)
-- Generating done (0.0s)
-- Build files have been written to: /root/utility_private/test_cmake/build
[root@vbox build]# ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile
Building the Project with CMake

After configuring and editing the CMakeLists.txt, you can generate and compile the project using the following commands:

mkdir build && cd build
cmake ..
make
Manually Compiling the Project
g++ demo1.cpp -o demo1 -std=c++11 -I/usr/local/include -L/usr/local/lib64 -lyaml-cpp

Leave a Comment