CMakeLists.txt语法介绍

一、常用命令

1.指定最小版本

//设置cmake需要的最低版本号
cmake_minimum_required(VERSION 3.6)

2.设置项目名称

//生成test.sln的工程名称
project(test)

3.基本指令

//生成可执行程序
add_executable(test, main.cpp)

//生成静态库
add_library(libstatic STATIC libstatic.cpp)

//生成动态库
add_library(dlldemo SHARED libdemo.cpp)

//遍历子文件夹中的CMakeLists.txt
add_subdirectory(subdir)
    
//设置包含的目录
include_directories(${PROJECT_SOURCE_DIR}/include)

//搜索所有的cpp文件
aux_source_directory(. SRC_LIST)
    
//自定义搜索
file(GLOB SRC "*.cpp" "subdir1/*cpp")
    
//连接库
target_link_libraries(test libadd.lib)

//将dll lb安装到指定的文件夹下
install(TARGETS libswap
        RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/bin
        LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/lib
        ARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/lib)
    
//将文件中的.h文件安装到指定文件夹下
file(GLOB head_files *.h)
install(FILES  ${head_files} DESTINATION ${PROJECT_SOURCE_DIR}/include)

4.设置变量

//在编译选项中加入C++11支持
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

//将当前编译的静态库或者动态库输出到当前项目文件夹lib子目录下    
set(LIBRARY_OUTPUT_PATH  ${PROJECT_SOURCE_DIR}/lib)
 
//设定可执行二进制文件的目录
set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
//设置变量的值,用一个变量代替多个
set(SRC main.cpp test.cpp)

5.打印消息

//输出正常
message(STATUS "build type:")
    
//输出警告
 message(WARNING "Enter cmake ${CMAKE_CURRENT_LIST_DIR}")
  
//输出错误
message(FATAL_ERROR "Opencv Not Found!")

6.常用变量

变量名含义
PROJECT_NAMEproject命令中写的项目名
CMAKE_VERSION当前使用CMake的版本
CMAKE_SOURCE_DIR工程顶层目录,即入口CMakeLists文件所在路径
PROJECT_SOURCE_DIR工程顶层目录,即入口CMakeLists文件所在路径
CMAKE_BINARY_DIR工程编译发生的目录,即执行cmake命令进行项目配置的目录,一般为build
PROJECT_BINARY_DIRCMAKE_BINARY_DIR
CMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt所在的路径
CMAKE_INSTALL_PREFIX指定make install命令执行时包安装路径
LIBRARY_OUTPUT_PATH重新定义目标链接库文件的存放位置
EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置
CMAKE_MODULE_PATH定义了cmake 模块(XXX.cmake)所在的路径

7.开关选项

变量名含义
CMAKE_BUILD_TYPE编译选项,Release或者Debug,如set(CMAKE_BUILD_TYPE "Release")
CMAKE_CXX_FLAGS设置C++11编译,set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
CMAKE_C_FLAGS设置C编译选项
CMAKE_CXX_COMPILER指定C编译器
CMAKE_C_COMPILER指定C++编译器
BUILD_SHARED_LIBS控制默认的库编译方式。如果未进行设置,使用ADD_LIBRARY时又没有指定库类型,默认编译生成的库都是静态库,如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库

8.链接外部库

在CMakeLists.txt中使用第三方库需要知道头文件、lib和dll。

find_package的作用就是去寻找该库的头文件位置、库文件位置以及库文件名称,并将其设为变量,返回提供给CMakeLists.txt其他部分使用。

find_pacage()方法签名如下:

find_package(<package> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [NO_POLICY_SCOPE])

QUITE 参数指代,当查找出错时,屏蔽 message() 的输出。 REQUIRED 参数指代,当找不到 package 时,终止过程。

现在用 XXX 代表要查找的 package 名字

find_pacakge(XXX REQUIRED)会设置一系列变量。

XXX_FOUND 代表库是否查找成功
XXX_INCLUDE_DIRS 代表头文件的路径
XXX_LIBRARIES 代表库文件的路径

两种模式搜索库:

  • Module模式:搜索CMAKE_MODULE_PATH指定路径下的FindXXX.cmake文件,执行该文件从而找到XXX库。其中,具体查找库并给XXX_INCLUDE_DIRSXXX_LIBRARIES两个变量赋值的操作由FindXXX.cmake模块完成。

以opencv为例,并且该lib需要设置到环境变量中

//查找opencv
find_package(OpenCV REQUIRED)//(包的名称及最低版本)找到后面需要库和头文件的包
if (OpenCV_FOUND)
    message(STATUS "OpenCV library status:")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}" \n)
    
    #include headers
    include_directories(${OpenCV_INCLUDE_DIRS})
    #target generation
    add_executable(OpenCV_test main.cpp)
    #link libraries
    target_link_libraries(OpenCV_test ${OpenCV_LIBS})
else ()
    message(FATAL_ERROR "Could not locate OpenCV" \n)
endif()
  • Config模式:搜索XXX_DIR指定路径下的XXXConfig.cmake或者XXX-config.cmake文件,执行该文件从而找到XXX库。其中具体查找库并给XXX_INCLUDE_DIRSXXX_LIBRARIES两个变量赋值的操作由XXXConfig.cmake模块完成。
1.法一
set(libtest_DIR E:/test/3rdparty)
find_package(libtest_DIR REQUIRED)

2.法二
//Find 3rdparty/libtest
find_package(libtest REQUIRED HINTS "${CMAKE_SOURCE_DIR}/3rdparty")
if(NOT libtest_FOUND)
  message(FATAL_ERROR "libtest Not Found!")
endif()
include_directories(${libtest_DIR})
target_link_libraries(main "${libtest_DIR}/libtest.lib")

在3rdparty/libtest的文件夹下创建一个libtestConfig.cmake文件,内容如下:

include(FindPackageHandleStandardArgs)

9.例子

9.1 单个cpp

cmake_minimum_required(VERSION 3.6)

# Name the project
project(LEETCODE)

if(MSVC)
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()

add_executable(LeetCode src/LeetCode.cpp)
message(${PROJECT_SOURCE_DIR})
message(${CMAKE_INSTALL_PREFIX})

# Install the executeable program in the bin folder of the
# current project directory.
install(TARGETS LeetCode DESTINATION ${PROJECT_SOURCE_DIR}/bin)

9.2 多个cpp和外部库

cmake_minimum_required(VERSION 3.6)

# Name the project
project(test)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

if(MSVC)
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()

find_package(add REQUIRED HINTS "${CMAKE_SOURCE_DIR}/3rdparty")
if(NOT add_FOUND)
	message(FATAL_ERROR "lib add Not Found")
endif()
	
include_directories(${PROJECT_SOURCE_DIR}/include ${add_DIR})

#add_executable(test src/main.cpp src/swap/swap.cpp)

#遍历目录中的所有文件
#file(GLOB_RECURSE SRC_LIST "*.cpp" "*.c")
#message(STATUS ${SRC_LIST})
add_executable(test src/main.cpp src/swap/swap.cpp)

target_link_libraries(test ${add_DIR}/libadd.lib)

install(TARGETS test DESTINATION ${PROJECT_SOURCE_DIR}/bin)

9.3 多个cpp和子文件中文件编译成dll  

//libswap在编译的时候生成dll
cmake_minimum_required(VERSION 3.6)

# Name the project
project(test)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

if(MSVC)
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()

find_package(add REQUIRED HINTS "${CMAKE_SOURCE_DIR}/3rdparty")
if(NOT add_FOUND)
	message(FATAL_ERROR "lib add Not Found")
endif()
	
include_directories(${PROJECT_SOURCE_DIR}/include ${add_DIR})

add_subdirectory(./src/swap)

add_executable(test src/main.cpp)

#win生成的libswap在lib/Debug文件夹下,Release模式在Release文件夹下
#target_link_libraries(test ${add_DIR}/libadd.lib ${PROJECT_SOURCE_DIR}/lib/Debug/libswap.lib)

#直接使用libswap就可以
target_link_libraries(test ${add_DIR}/libadd.lib libswap)

install(TARGETS test DESTINATION ${PROJECT_SOURCE_DIR}/bin)
//swap文件下的CMakeLists.txt
aux_source_directory(. SUB_SRC)

file(GLOB head_files *.h)

add_library(libswap SHARED ${SUB_SRC})         

#set(head_files swap.h 1.h ${PROJECT_SOURCE_DIR}/3rdparty/add/add.h)

install(FILES  ${head_files} DESTINATION ${PROJECT_SOURCE_DIR}/include)

#将dll lb安装到制定的文件夹下
install(TARGETS libswap
        RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/bin
        LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/lib
        ARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/lib)

//main.cpp
#include "swap.h"
#include "add.h"
#include <string>

int main()
{
	CTest obj(2,8);
	obj.swap();

	dllTest::CAdd add;
	std::cout<<"dll sum = "<< add.sum(1, 6);
	dllTest::show();
}
#pragma once
#ifdef libswap_EXPORTS
#ifdef __GNUC__
#ifndef __linux__
#define DLL_TEST_API __attribute__((dllexport))
#else
#define DLL_TEST_API __attribute__((visibility("default")))
#endif
#else
#define DLL_TEST_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#ifndef __linux__
#define DLL_TEST_API __attribute__((dllimport))
#else
#define DLL_TEST_API __attribute__((visibility("default")))
#endif
#else
#define DLL_TEST_API
#endif
#endif
#include <iostream>

class DLL_TEST_API CTest
{
public:
    CTest(int a, int b)
	{
        this->a = a;
        this->b = b;
    }
    void swap();
private:
    int a;
    int b;
};


//swap.cpp
#include "swap.h"

void CTest::swap()
{
	std::cout<<"before:"<<std::endl;
	std::cout << "a = " << a << std::endl;
	std::cout << "b = " << b << std::endl;
    int temp;
    temp  = a;
    a = b;
    b = temp;
	
	std::cout<<"after:"<<std::endl;
	std::cout << "a = " << a << std::endl;
    std::cout << "b = " << b << std::endl;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值