CMakeLists.txt 学习笔记

发布于:2025-08-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

内部构建(in source build)

编写源代码main.c

#include <stdio.h>

void main()
{
    printf("hello\n");
}

编写CMakeLists.txt

project(hello)
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
message(STATUS "hello_SOURCE_DIR: ${hello_SOURCE_DIR}")
message(STATUS "hello_BINARY_DIR: ${hello_BINARY_DIR}")

set(src_list main.c)
message(STATUS "src_list: ${src_list}")
add_executable(hello ${src_list})

目录结构如下

t1
├── CMakeLists.txt
└── main.c

执行命令

cd t1 && cmake .

打印内容如下

PROJECT_SOURCE_DIR: /home/Jack/backup/cmake/t1
PROJECT_BINARY_DIR: /home/Jack/backup/cmake/t1
hello_SOURCE_DIR: /home/Jack/backup/cmake/t1
hello_BINARY_DIR: /home/Jack/backup/cmake/t1
src_list: main.c

此时,目录结构如下

t1
├── CMakeCache.txt
├── CMakeFiles
├── CMakeLists.txt
├── Makefile
├── cmake_install.cmake
└── main.c

执行命令

cd t1 && make

此时,目录结构如下

t1
├── CMakeCache.txt
├── CMakeFiles
├── CMakeLists.txt
├── Makefile
├── cmake_install.cmake
├── hello
└── main.c

运行程序

cd t1 && ./hello

结果如下

hello

外部构建(out of source build)

新建名为 t2 的文件夹,将 t1 中的 main.c 和 CMakeLists.txt 拷贝到 t2 中,目录结构如下

t2
├── CMakeLists.txt
└── main.c

在 t2 中新建 build 文件夹

cd t2 && mkdir build

在 build 文件夹中执行 cmake 命令

cd t2/build && cmake ..

打印内容如下

PROJECT_SOURCE_DIR: /home/Jack/backup/cmake/t2
PROJECT_BINARY_DIR: /home/Jack/backup/cmake/t2/build
hello_SOURCE_DIR: /home/Jack/backup/cmake/t2
hello_BINARY_DIR: /home/Jack/backup/cmake/t2/build

此时,目录结构如下

t2
├── CMakeLists.txt
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── Makefile
│   └── cmake_install.cmake
└── main.c

执行命令

cd t2/build && make

此时,目录结构如下

t2
├── CMakeLists.txt
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── Makefile
│   ├── cmake_install.cmake
│   └── hello
└── main.c

运行程序

cd t2/build && ./hello

结果如下

hello

更好一点的 hello 工程

将 t2 的 main.c 拷贝到 t3 的 src 中,目录结构如下

t3
├── CMakeLists.txt
├── LICENSE
├── README.md
├── build
├── doc
│   └── hello.txt
├── runhello.sh
└── src
    ├── CMakeLists.txt
    └── main.c

编写第1个CMakeLists.txt

project(hello)
add_subdirectory(src bin)
set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/install)
install(FILES LICENSE README.md DESTINATION doc)
install(DIRECTORY doc/ DESTINATION doc)
install(PROGRAMS runhello.sh DESTINATION bin)

编写第2个CMakeLists.txt

add_executable(hello main.c)

执行命令

cd t3/build && cmake .. && make install

此时,目录结构如下

t3
├── CMakeLists.txt
├── LICENSE
├── README.md
├── build
│   ├── bin
│   │   └── hello
│   └── install
│       ├── bin
│       │   └── runhello.sh
│       └── doc
│           ├── LICENSE
│           ├── README.md
│           └── hello.txt
├── doc
│   └── hello.txt
├── runhello.sh
└── src
    ├── CMakeLists.txt
    └── main.c

构建动态库与静态库

目录结构如下

t4
├── CMakeLists.txt
├── build
└── lib
    ├── CMakeLists.txt
    ├── hello.c
    └── hello.h

编写第1个CMakeLists.txt

project(hellolib)
add_subdirectory(lib)
set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/install)

编写第2个CMakeLists.txt

set(LIBHELLOSRC hello.c)
add_library(hello SHARED ${LIBHELLOSRC})
add_library(hello_static STATIC ${LIBHELLOSRC})
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
install(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(FILES hello.h DESTINATION include/hello)

编写hello.h

#ifndef HELLO_H
#define HELLO_H

#include <stdio.h>
void HelloFunc();

#endif

编写hello.c

#include "hello.h"

void HelloFunc()
{
	printf("hello\n");
}

执行命令

cd t4/build && cmake .. && make install

此时,目录结构如下

t4
├── CMakeLists.txt
├── build
│   ├── install
│   │   ├── include
│   │   │   └── hello
│   │   │       └── hello.h
│   │   └── lib
│   │       ├── libhello.a
│   │       └── libhello.so
│   └── lib
│       ├── libhello.a
│       └── libhello.so
└── lib
    ├── CMakeLists.txt
    ├── hello.c
    └── hello.h

如何使用外部共享库和头文件

将 t4 的头文件、库文件拷贝到 t5 的 3rdparty 中,目录结构如下

t5
├── 3rdparty
│   └── hello
│       ├── include
│       │   └── hello
│       │       └── hello.h
│       └── lib
│           ├── libhello.a
│           └── libhello.so
├── CMakeLists.txt
├── build
└── src
    ├── CMakeLists.txt
    └── main.c

编写第1个CMakeLists.txt

project(newhello)
add_subdirectory(src)

编写第2个CMakeLists.txt

include_directories(${PROJECT_SOURCE_DIR}/3rdparty/hello/include/hello)
add_executable(main main.c)
target_link_libraries(main ${PROJECT_SOURCE_DIR}/3rdparty/hello/lib/libhello.so)

编写main.c

#include "hello.h"

int main()
{
	HelloFunc();
	return 0;
}

执行命令

cd t5/build && cmake .. && make

此时,目录结构如下

t5
├── 3rdparty
│   └── hello
│       ├── include
│       │   └── hello
│       │       └── hello.h
│       └── lib
│           ├── libhello.a
│           └── libhello.so
├── CMakeLists.txt
├── build
│   └── src
│       └── main
└── src
    ├── CMakeLists.txt
    └── main.c

运行程序

cd t5/build/src && ./main

结果如下

hello

常用指令

可以使用如下命令查看 set 指令的解释

cmake --help-command set

set - Set a variable to a given value.

set(<variable> <value>)

message - Display a message to the user.

message([<mode>] "message to display")

add_executable - Add an executable to the project using the specified source files.

add_executable(<name> source1 [source2 ...])

project - Set a name for the entire project.

project(<PROJECT-NAME>)

PROJECT_SOURCE_DIR - 工程路径,和 hello_SOURCE_DIR 等价,hello 是 project name
PROJECT_BINARY_DIR - 编译路径,和 hello_BINARY_DIR 等价,hello 是 project name

add_subdirectory - Add a subdirectory to the build.

add_subdirectory(source_dir [binary_dir])

install - Specify rules to run at install time.

// Installing Files
install(<FILES|PROGRAMS> files... DESTINATION <dir>)

// Installing Directories
install(DIRECTORY dirs... DESTINATION <dir>)

add_library - Add a library to the project using the specified source files.

add_library(<name> [STATIC | SHARED | MODULE] source1 [source2 ...])

include_directories - Add the given directories to those the compiler uses to search for include files.

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

网站公告

今日签到

点亮在社区的每一天
去签到