cmake tutorial

Demo

1
2
3
.
|-- CMakeLists.txt
`-- main.c

main.c

1
2
3
4
5
6
7
8
#include <stdio.h>
#include "testFunc.h"

int main(void)
{
printf("Hello World\n");
return 0;
}

CMakeLists.txt

1
2
3
4
5
cmake_minimum_required (VERSION 2.8)

project (demo)

add_executable(main main.c)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@8bdf5f3b23af demo]# cmake .
-- The C compiler identification is GNU 8.2.1
-- The CXX compiler identification is GNU 8.2.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /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: /usr/bin/c++
-- Check for working CXX compiler: /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: /root/labc/demo

command generated MakeFile, and some auto generate file.

1
2
3
4
5
6
7
.
|-- CMakeCache.txt
|-- CMakeFiles
|-- CMakeLists.txt
|-- Makefile
|-- cmake_install.cmake
`-- main.c

1
2
3
4
5
[root@8bdf5f3b23af demo]# make
Scanning dependencies of target main
[ 50%] Building C object CMakeFiles/main.dir/main.c.o
[100%] Linking C executable main
[100%] Built target main

make and execute

1
2
[root@8bdf5f3b23af demo]# ./main
Hello World

Multi-source filie under one directory

1
2
3
4
5
.
|-- CMakeLists.txt
|-- main.c
|-- testFunc.c
`-- testFunc.h

testFunc.c

1
2
3
4
5
6
7
8
9
10
11
/*
* testFunc.c
*/

#include <stdio.h>
#include "testFunc.h"

void func(int data)
{
printf("data is %d\n", data);
}

testFunc.h

1
2
3
4
5
6
7
8
9
10
/*
* testFunc.h
*/

#ifndef _TEST_FUNC_H_
#define _TEST_FUNC_H_

void func(int data);

#endif

main.c

1
2
3
4
5
6
7
8
#include <stdio.h>
#include "testFunc.h"

int main(void)
{
func(100);
return 0;
}

CMakeLists.txt

1
2
3
4
5
cmake_minimum_required (VERSION 2.8)

project (demo)

add_executable(main main.c testFunc.c)

add testFunc.c to executable param

make and execute

1
2
[root@8bdf5f3b23af multsource]# ./main
data is 100

if we have a lot of source file, add_executable is troublesome.
aux_source_directory can take files under directory as a source.

add another function

1
2
3
4
5
6
7
8
.
|-- CMakeLists.txt
|-- main
|-- main.c
|-- testFunc.c
|-- testFunc.h
|-- testFunc1.c
`-- testFunc1.h

modify CMakeLists

1
2
3
4
5
6
7
cmake_minimum_required (VERSION 2.8)

project (demo)

aux_source_directory(. SRC_LIST)

add_executable(main ${SRC_LIST})

make and execute

1
2
3
[root@8bdf5f3b23af multsource1]# ./main
data is 100
data is 200

Multi-source filie under multi-directory

1
2
3
4
5
6
7
8
9
10
.
|-- CMakeLists.txt
|-- main
|-- main.c
|-- test_func
| |-- testFunc.c
| `-- testFunc.h
`-- test_func1
|-- testFunc1.c
`-- testFunc1.h

group function by two directory test_func test_func1

modify CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
cmake_minimum_required (VERSION 2.8)

project (demo)

include_directories (test_func test_func1)

aux_source_directory (test_func SRC_LIST)
aux_source_directory (test_func1 SRC_LIST1)

add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})

result is same as above.

Formal structure

1
2
3
4
5
6
7
8
9
10
11
12
13
.
|-- CMakeLists.txt
|-- bin
|-- build
|-- include
| |-- testFunc.h
| `-- testFunc1.h
|-- main
`-- src
|-- CMakeLists.txt
|-- main.c
|-- testFunc.c
`-- testFunc1.c
  1. put source file to src
  2. put head file to include
  3. build used to store middle file
  4. bin used to store executable file

outside CMakeLists.txt

1
2
3
4
5
cmake_minimum_required (VERSION 2.8)

project (demo)

add_subdirectory (src)

inside CMakeLists.txt

1
2
3
4
5
6
7
aux_source_directory (. SRC_LIST)

include_directories (../include)

add_executable (main ${SRC_LIST})

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

  • EXECUTABLE_OUTPUT_PATH : executable file path
  • PROJECT_SOURCE_DIR : project root

result is same as above.

Dynamic and static libraries

1
2
3
4
5
6
7
8
.
|-- CMakeLists.txt
|-- build
|-- lib
`-- lib_testFunc
|-- CMakeLists.txt
|-- testFunc.c
`-- testFunc.h

outside CMakeLists.txt

1
2
3
4
5
cmake_minimum_required (VERSION 2.8)

project (demo)

add_subdirectory (lib_testFunc)

inside CMakeLists.txt

1
2
3
4
5
6
7
8
9
aux_source_directory (. SRC_LIST)

add_library (testFunc_shared SHARED ${SRC_LIST})
add_library (testFunc_static STATIC ${SRC_LIST})

set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

  • add_library: generate dynamic or static libraries, (1. libname; 2. dynamic or static, static in default; 3. source file path)
  • set_target_properties: setting output name, can set other options like lib version
  • LIBRARY_OUTPUT_PATH: default path of library file

in build run cmake . and make

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
|-- CMakeLists.txt
|-- build
| |-- CMakeCache.txt
| |-- CMakeFiles
| |-- Makefile
| |-- cmake_install.cmake
| `-- lib_testFunc
|-- lib
| |-- libtestFunc.a
| `-- libtestFunc.so
`-- lib_testFunc
|-- CMakeLists.txt
|-- testFunc.c
`-- testFunc.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.
|-- CMakeLists.txt
|-- bin
|-- build
|-- lib
| |-- libtestFunc.a
| `-- libtestFunc.so
|-- lib_testFunc
| |-- CMakeLists.txt
| |-- testFunc.c
| `-- testFunc.h
`-- src
|-- CMakeLists.txt
`-- main.c

outside CMakeLists.txt

1
2
3
4
5
6
7
cmake_minimum_required (VERSION 2.8)

project (demo)

add_subdirectory (lib_testFunc)

add_subdirectory (src)

inside CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
11
12
aux_source_directory (. SRC_LIST)

# find testFunc.h
include_directories (../lib_testFunc)

link_directories (${PROJECT_SOURCE_DIR}/lib)

add_executable (main ${SRC_LIST})

target_link_libraries (main testFunc)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

  • link_directories : Add non-standard shared library search path
  • target_link_libraries : Link the target file with the library file

Compile options

1
2
3
4
5
.
|-- CMakeLists.txt
|-- bin
|-- build
`-- main.cpp

main.cpp

1
2
3
4
5
6
7
8
#include <iostream>

int main(void)
{
auto data = 100;
std::cout << "data: " << data << "\n";
return 0;
}

CMakeLists.txt

1
2
3
4
5
6
7
8
9
cmake_minimum_required (VERSION 2.8)

project (demo)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

add_compile_options(-std=c++11 -Wall)

add_executable(main main.cpp)

Compile control

1
2
3
4
5
6
7
8
.
|-- CMakeLists.txt
|-- bin
|-- build
`-- src
|-- CMakeLists.txt
|-- main1.c
`-- main2.c

outside CMakeLists.txt

1
2
3
4
5
6
7
8
9
cmake_minimum_required(VERSION 2.8)

project(demo)

option(MYDEBUG "enable debug compilation" OFF)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

add_subdirectory(src)

add an option MYDEBUG

inside CMakeLists.txt

1
2
3
4
5
6
7
8
9
cmake_minimum_required (VERSION 2.8)

add_executable(main1 main1.c)

if (MYDEBUG)
add_executable(main2 main2.c)
else()
message(STATUS "Currently is not in debug mode")
endif()

user MYDEBUG to decide whether or not compile main2
cmake .. -DMYDEBUG=ON && make

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
|-- CMakeLists.txt
|-- bin
| |-- main1
| `-- main2
|-- build
| |-- CMakeCache.txt
| |-- CMakeFiles
| |-- Makefile
| |-- cmake_install.cmake
| `-- src
`-- src
|-- CMakeLists.txt
|-- main1.c
`-- main2.c

https://blog.csdn.net/whahu1989/article/details/82078563