目录
1 常用命令
(1)configure_file
(2).cmake文件
(3) install
(4)include_directories
(5) add_subdirectory
(6) find_library
(7)target_link_libraries
2 cmake 生成库文件
(1)目录结构
(2) 代码
3 cmake调用库文件
(1)目录结构
(2)代码
1 常用命令
(1)configure_file
在 CMake 中,configure_file
命令用于复制一个源文件到一个目标位置,并在复制的过程中替换源文件中的某些变量。这对于生成配置头文件特别有用,其中某些值(如路径、版本号等)需要在构建时确定。
(2).cmake文件
file(GLOB FREECAD_HELPER_CMAKE_FILES ./*.cmake)
set(_SKIP_FILES "SetupQt.cmake")
foreach(_CMAKE_FILE ${FREECAD_HELPER_CMAKE_FILES})
get_filename_component(_FILENAME ${_CMAKE_FILE} NAME)
if (NOT _FILENAME IN_LIST _SKIP_FILES)
include(${_CMAKE_FILE})
endif()
endforeach(_CMAKE_FILE ${FREECAD_HELPER_CMAKE_FILES})
(3) install
在 CMake 中,install()
命令用于指定构建目标在安装时应该被复制到哪里。这通常用于安装库、头文件、可执行文件等,以便其他项目或用户可以使用它们。
# CMakeLists.txt
add_executable(my_program main.cpp)
# 安装可执行文件到 /usr/local/bin 目录
install(TARGETS my_program DESTINATION bin)
# CMakeLists.txt
add_library(my_library my_library.cpp)
# 安装库文件到 /usr/local/lib 目录
install(TARGETS my_library DESTINATION lib)
# CMakeLists.txt
include_directories(include)
# 安装头文件到 /usr/local/include/my_project 目录
install(FILES include/my_header.h DESTINATION include/my_project)
# CMakeLists.txt
# 安装多个文件到不同目录
install(FILES file1.txt file2.txt DESTINATION share/my_project)
# 安装整个目录及其内容
install(DIRECTORY doc/ DESTINATION share/my_project/docs)
(4)include_directories
在 CMake 中,include_directories()
命令用于向编译器添加包含目录,使得在编译源文件时可以找到所需的头文件。这通常用于指定项目中的头文件目录,或者是第三方库的头文件目录。
# 添加多个头文件目录
include_directories(
include
third_party/library1/include
third_party/library2/include
)
(5) add_subdirectory
add_subdirectory
是 CMake 中的一个命令,用于将子目录添加到构建过程中。这个命令的作用是在当前 CMakeLists.txt
文件的对应位置包含子目录中的 CMakeLists.txt
文件,并执行其中的命令。这使得项目的组织和管理变得更为容易和高效。
cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 添加子目录 src 到构建中
add_subdirectory(src)
# 在父目录的 CMakeLists.txt 中,你还可以链接子目录中定义的目标
target_link_libraries(MyApp MyLib) # 假设 MyLib 是在 src 目录中定义的目标
(6) find_library
find_library(CMAKE_LIB cmake_library HINTS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
# 打印PROJECT_SOURCE_DIR变量的值
message(STATUS "PROJECT_SOURCE_DIR is: ${PROJECT_SOURCE_DIR}")
# 如果CMAKE_LIB变量被成功设置(即库被找到),你也可以打印它的值
if(CMAKE_LIB)
message(STATUS "Found library: ${CMAKE_LIB}")
else()
message(FATAL_ERROR "Library not found!")
endif()
find_library(<VARNAME> name [path1 path2 ...]
[NO_DEFAULT_PATH] [NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH] [NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH] [CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH])
-
<VARNAME>
:一个变量名,用于存储找到的库的完整路径。 -
name
:要查找的库的名字,不带前缀(比如lib
)和后缀(比如.so
,.a
,.dylib
,.lib
等)。 -
path1 path2 ...
:可选参数,指定额外的路径来搜索库文件。
(7)target_link_libraries
target_link_libraries(cmake_test PRIVATE Qt5::Widgets ${CMAKE_LIB})
在 CMake 中,target_link_libraries
命令用于指定一个目标(例如库或可执行文件)需要链接的库。这个命令将库添加到目标的链接器命令中,以便在构建目标时能够解析目标中的外部符号。
在你提供的命令 target_link_libraries(cmake_test PRIVATE Qt5::Widgets ${CMAKE_LIB})
中:
-
cmake_test
是你想要链接库的目标名。 -
PRIVATE
是一个关键字,它指定了链接库的可见性范围。PRIVATE
表示这个库只会被cmake_test
目标使用,并且不会传递给依赖于cmake_test
的其他目标。CMake 提供了几种可见性范围,包括PUBLIC
、PRIVATE
和INTERFACE
,它们决定了库是如何被传播到依赖目标的。 -
Qt5::Widgets
是一个由find_package(Qt5 COMPONENTS Widgets)
提供的导入目标,它代表 Qt5 Widgets 模块。使用导入目标而不是直接指定库文件路径是 CMake 推荐的做法,因为它可以自动处理库的依赖关系和其他平台相关的细节。 -
${CMAKE_LIB}
是一个变量,它应该在 CMakeLists.txt 文件的某个地方被定义。这个变量可能包含了一个或多个需要链接的库名或库文件路径。使用${...}
语法是 CMake 中获取变量值的方式。
这个命令的意思是:为 cmake_test
目标链接 Qt5 的 Widgets 模块,并链接由 ${CMAKE_LIB}
变量指定的库。
确保你已经通过 find_package
或其他方式找到了 Qt5 Widgets 模块,并且已经定义了 CMAKE_LIB
变量。如果 CMAKE_LIB
变量没有被正确设置,这个命令将不会按预期工作。通常,CMAKE_LIB
变量可能是在 CMakeLists.txt 文件的某个地方通过 find_library
或其他方式设置的。
2 cmake 生成库文件
(1)目录结构
(2) 代码
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(cmake_library LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 COMPONENTS Core REQUIRED)
add_library(cmake_library SHARED
cmake_library_global.h
cmake_library.cpp
cmake_library.h
)
target_link_libraries(cmake_library PRIVATE Qt5::Core)
target_compile_definitions(cmake_library PRIVATE CMAKE_LIBRARY_LIBRARY)
cmake_library_global.h
#ifndef CMAKE_LIBRARY_GLOBAL_H
#define CMAKE_LIBRARY_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CMAKE_LIBRARY_LIBRARY)
# define CMAKE_LIBRARY_EXPORT Q_DECL_EXPORT
#else
# define CMAKE_LIBRARY_EXPORT Q_DECL_IMPORT
#endif
#endif // CMAKE_LIBRARY_GLOBAL_H
cmake_library.h
#ifndef CMAKE_LIBRARY_H
#define CMAKE_LIBRARY_H
#include "cmake_library_global.h"
class CMAKE_LIBRARY_EXPORT Cmake_library
{
public:
Cmake_library();
int add(int a,int b);
};
#endif // CMAKE_LIBRARY_H
cmake_library.cpp
#include "cmake_library.h"
Cmake_library::Cmake_library()
{
}
int Cmake_library::add(int a, int b)
{
return a + b;
}
3 cmake调用库文件
(1)目录结构
(2)代码
外层CMakeLists.txt
project(cmake_test LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(src bin)
src/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_library(CMAKE_LIB cmake_library HINTS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
# 打印PROJECT_SOURCE_DIR变量的值
message(STATUS "PROJECT_SOURCE_DIR is: ${PROJECT_SOURCE_DIR}")
# 如果CMAKE_LIB变量被成功设置(即库被找到),你也可以打印它的值
if(CMAKE_LIB)
message(STATUS "Found library: ${CMAKE_LIB}")
else()
message(FATAL_ERROR "Library not found!")
endif()
include_directories (../inc/)
set(SRC_LIST
main.cpp
mainwindow.cpp
../inc/mainwindow.h
)
add_executable(cmake_test
${SRC_LIST}
)
target_link_libraries(cmake_test PRIVATE Qt5::Widgets ${CMAKE_LIB})