CMake进阶
文章平均质量分 56
整理在项目实践过程中使用CMake的经验和技术问题
10km
这个作者很懒,什么都没留下…
展开
-
cmake: MinGW编译时为httplib.h增加连接库支持
httplib.h是一个只有一个头文件的C++11语言的跨平台 HTTP/HTTPS 库。如果使用在自己的项目中,在MinGW下编译时,会报连接错误,因为找不到socket相关库。所以在连接时需要参照httplib.h中对MSVC的库依赖,添加ws2_32,crypt32,cryptui几个库的#ifdef _MSC_VER#pragma comment(lib, "ws2_32.lib")#pragma comment(lib, "crypt32.lib")#pragma comment(li原创 2022-03-27 16:53:06 · 1202 阅读 · 0 评论 -
conan入门(二十四):通过CONAN_DISABLE_CHECK_COMPILER禁用编译器检查
conan 通过CONAN_DISABLE_CHECK_COMPILER禁用编译器检查最近工作的一个单片机项目项目,用了一款不知名的芯片,坑爹的开发商提供的编译器中有C++编译器,但是不能正常工作。好在我们的项目是纯C项目不需要C++编译器,只要在项目的cmake脚本中project命令指定为Cproject($NAME LANGUAGE C),这个坑就暂且绕过。项目结构成型我打算将项目编译转为使用conan来管理。在安装项目的依赖库cjson的时候,出错了。cjson/1.7.15: Copying原创 2022-03-26 15:50:21 · 4784 阅读 · 0 评论 -
cmake:通过CMAKE_CXX_COMPILE_FEATURES判断编译器是否支持C++11
以前在cmake中要判断一个编译器是否支持C++11挺麻烦的,要根据编译器的类型和版本来判断。从cmake 3.1版本开始增加了一个CMAKE_CXX_COMPILE_FEATURES变量用于获取当前C++ 编译器支持的编译特性列表,列表中是一些定义在CMAKE_CXX_KNOWN_FEATURES(C++已知特性)中的特性名字,比如cxx_lambdas即为当前编译器支持lambda表达式。从cmake 3.8版本开始,cmake可识别的编译特性增加了代表C++标准的特性名:cxx_std_98,cx原创 2022-03-03 15:13:33 · 2882 阅读 · 0 评论 -
cmake:ESP32交叉编译工具链定义
ESP32的SDK(ESP-IDF)本身提供了esp32平台的cmake toolchain文件:esp-idf-v4.4\tools\cmake\toolchain-esp32.cmake 1就是esp32的工具链文件定义样板。如下:set(CMAKE_SYSTEM_NAME Generic)set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc)set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++)set(CMAKE_ASM_CO原创 2022-02-12 10:54:24 · 5406 阅读 · 0 评论 -
cmake:Windows编译支持HTTPS的curl库及find_package查找CURL时需要注意的问题
curl是一个成熟的HTTP client库,现在windows平台下可以使用cmake在命令行完成编译。build curl以下脚本实现Windows CMD下使用cmake及VS2015编译curlcd curlmkdir buildcd build# 生成Visual Studio 2015工程文件cmake .. -G "Visual Studio 14 2015 Win64" ^ -DCMAKE_INSTALL_PREFIX=J:\curl-vc140-x64 ^ -DBUILD原创 2022-02-07 18:01:34 · 5064 阅读 · 0 评论 -
cmake:基于MDK(Keil)的Nationstech.N32G45x平台交叉编译工具链定义
Keil MDK是非常常用的单片机开发集成环境,Keil公司2005年由ARM公司收购,现在是ARM主要的嵌入系统开发平台(ARM的另一个开发环境ds-5早在九年前就停止更新了)。Keil虽然是个集成开发环境,但Keil本身其实是由μVision IDE和arm编译器构成。cmake虽然目前不支持生成μVision的工程文件,但cmake完全可以使用MDK中提供的arm编译器来实现独立于μVision的交叉编译(说到底μVision只是一个为开发者提供易用的GUI界面,真正干活的还是编译器)。cmake原创 2022-02-06 15:36:07 · 2174 阅读 · 0 评论 -
cmake:解决MSVC下/MT 编译paho.mqtt.c的问题
paho.mqtt.c是eclipse开发的C语言跨平台mqtt client 开源库,之前写过一篇博客《cmake:VS2015和GCC编译paho.mqtt C/C++ client》介绍如何编译它。最近在使用的时候发现有个问题:paho.mqtt.c在MSVC编译的时候不能支持/MT编译。compiler_flag_overrides.cmake为了以/MT编译paho.mqtt.c,在不修改paho.mqtt.c项目代码的情况需要使用CMAKE_USER_MAKE_RULES_OVERRIDE原创 2022-01-06 11:41:49 · 1667 阅读 · 0 评论 -
cmake:用于搜索mysql的FindMySQL.cmake及bug溯源及修复
最近设计一个需要mysql的项目,构建项目的时候需要find_package查找mysql 库安装位置,cmake默认没有提供mysql的find_package支持.好在mysql官方是提供了,在github上mysql-connector-odbc项目找到了https://github.com/mysql/mysql-connector-odbc/blob/master/cmake/FindMySQL.cmake有它就好办了。CMakeLists中添加mysql库原创 2022-01-06 11:09:16 · 3040 阅读 · 0 评论 -
cmake:gperftools性能分析工具find libprofiler 脚本暨profiler的静态连接问题
gperftools是一个很好用的性能分析工具,但没有提供官方的用于查找profiler库的cmake脚本,所以在基于cmake管理的项目中如果要在系统查找libprofiler库就就要自己写FindPROFILER.cmake脚本。将脚本所在的文件夹加入CMAKE_MODULE_PATH,调用find_package(PROFILER),就会找到系统中安装的gperftools的libprof...原创 2018-11-07 00:40:07 · 3582 阅读 · 1 评论 -
cmake+gcc解决extended initializer lists only available with -std=c++11 or -std=gnu++11
有时,我们需要一个结构体变量做为参数传递给函数,后面又不需要再用到这个结构体变量,所以如果专门定义一个变量,再将这个变量传递给函数就显得挺罗嗦。 就像下面这段代码,tmpStruct只是起到一个数据包装的作用,调用test()之后并不再用到,所以这个变量就显示有些多余 。#include struct _stA{ char *a; int b; int原创 2015-10-11 15:22:58 · 21879 阅读 · 2 评论 -
cmake 生成Makefile时指定c/c++编译器
linux下在使用cmake生成Makefile的时候,如果不指定编译器,则默认是使用系统原生的编译器, 当操作系统中安装了新的版本的编译器,两个版本编译器共存的时候,如果想使用新版本的编译,在cmake生成Makefile的时候就需要指定编译。这就是我目前遇到的情况: 我的项目代码是用C++11写的,需要支持C++11的编译,而我使用的CentOS6.5原生的编译器是gcc4.4.7(位置/u原创 2016-01-01 12:12:25 · 54952 阅读 · 1 评论 -
cmake:在各级子项目(目录)之间共享变量
项目目录结构如下图,facedetect和facefeature都要用到opencl中的include文件,1.2,2.0,2.1是不同的opencl版本的头文件,希望在cmake创建Makefile时,opencl文件夹下的CMakeLists.txt能定义类似INCLUDE_OPENCL_1_2,INCLUDE_OPENCL_2_0,INCLUDE_OPENCL_2_1,这样的变量,以保存不同版原创 2016-01-13 08:59:33 · 26529 阅读 · 2 评论 -
cmake:shell(bat,sh) 脚本方式生成Makefile
项目总体是用ant来控制编译的,但有一些用c/c++写的native的动态链接库是用cmake来生成Makefile文件编译的,为了统一用ant来控制所有代码的生成,就需要将c/c++代码也能用ant脚本编译。 总体的过程是这样的: 步骤1.为了让ant能控制c/c++代码的编译,首先就需将cmake生成Makefile的过程脚本化。 步骤2.在ant脚本中调用步骤1中的脚本来实现Makef原创 2016-01-01 11:46:30 · 4747 阅读 · 1 评论 -
cmake:让mingw(gcc)生成MSVC可用的dll(.lib)
minggw(gcc)编译出来的动态库(DLL),默认是没有MSVC连接动态库所需要的lib文件的。 关于MSVC的DLL和LIB的作用和区别,请参考这篇博文,讲得很透彻了–>《DLL和LIB的区别》那么如果VC要链接gcc生成的DLL,却没有lib文件怎么办? 对于这个问题网上都有解决的办法,这篇文章讲到一些办法,可供收藏《VC6 调用GCC的DLL》,对于没有提供lib的DLL都可以用这原创 2016-01-15 19:49:55 · 12052 阅读 · 11 评论 -
CMake Error: ...Missing variable is: CMAKE_FIND_LIBRARY_
今天在使用cmake的find_library命令时,cmake居然报错: CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly. Missing variable is: CMAKE_FIND_LIBRARY_PREFIXES意思就是CMAK原创 2016-04-29 16:26:26 · 3040 阅读 · 1 评论 -
cmake:install制作简单的安装脚本
当我们制作用于二次开发的SDK的时候,用cmake的install命令制作一个安装脚本提供简单的SDK安装功能,在make结束后自动把文件分类放在不同的目录下,提供给用户,比只是把.h,.lib,.dll文件一股脑的复制给用户,让用户自己去配置要好得多。 下面的cmake脚本片段,展示了用cmake install命令实现的简单安装功能:########安装脚本########### 将生成的t原创 2016-06-19 12:46:47 · 13499 阅读 · 0 评论 -
cmake:设置编译选项的讲究(add_compile_options和CMAKE_CXX_FLAGS的区别)
在cmake脚本中,设置编译选项可以通过add_compile_options命令,也可以通过set命令修改CMAKE_CXX_FLAGS或CMAKE_C_FLAGS。 使用这两种方式在有的情况下效果是一样的,但请注意它们还是有区别的: add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器),而set命令设置CMAKE_C_FLAGS或CMAKE_CX原创 2016-06-22 09:53:48 · 121428 阅读 · 0 评论 -
cmake设置msvc的运行库(runtime library)塈指定openjpeg使用静态库
cmake这个跨平台的make工具功能已经很强大了,但它也有不足的地方,就是本文的标题。 在用cmake生成NMake的Makefile或visual studio的.sln时,如何指定运行库(/MD /MT)? 原本,我以为可以在CMAKE的手册中找到一个command或PROPERTY或VARIABLE,简单的调用或设置一下就可以了,很遗憾,把整个CMAKE manual翻了几遍也没找到,没原创 2016-06-22 17:04:11 · 7550 阅读 · 0 评论 -
cmake:环境变量(environment variable)读写和if判断
cmake中对环境变量读写都是通过ENV前缀来访问环境变量 读取环境变量则要使用 $ENV{JAVA_HOME}这样的格式 写环境变量如下:set( ENV{PATH} /home/martink )if语句判断环境变量是否定义要用下面的格式if(NOT DEFINED ENV{JAVA_HOME}) # 没有找到JAVA_HOME环境变量 message(FATAL_ERRO原创 2016-06-27 17:08:23 · 46968 阅读 · 1 评论 -
cmake:EXCLUDE_FROM_ALL的用处
cmake 的add_library,add_executable,add_subdirectory等命令都有一个EXCLUDE_FROM_ALL参数. 这个参数的作用根据cmake官网的解释就是如果某个target或subdirectory被设置为EXCLUDE_FROM_ALL属性,那么这个target(或这个subdirectory中的所有target)就会被排除在all target列表之原创 2016-06-25 17:09:34 · 13099 阅读 · 0 评论 -
cmake:善用find_package()提高效率暨查找JNI支持
cmake提供了很多实用的cmake-modules,通过find_package()命令调用这些modules,用于写CMakeLists.txt脚本时方便的查找依赖的库或其他编译相关的信息,善用这些modules,可以提高写脚本的效率和脚本通用性。 说起来真的有点太抽象,举个我最近遇到的简单例子吧。 我们写java的JNI接口代码时,肯定是需要jni.h文件的,那么在写cmake脚本中,就需原创 2016-07-05 15:06:03 · 5264 阅读 · 1 评论 -
cmake:在Makefile中运行ant脚本
Apache Ant,是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,在Java开发环境中应用非常广泛。 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake,在c/c++跨平台开发中应用非常广泛 。 有的时候,我们原创 2016-07-05 17:21:44 · 1588 阅读 · 1 评论 -
cmake:用add_subdirectory()添加外部项目文件夹
一般情况下,我们的项目各个子项目都在一个总的项目根目录下,但有的时候,我们需要使用外部的文件夹,怎么办呢? add_subdirectory命令,可以将指定的文件夹加到build任务列表中。下面是将与当前项目平级的一个目录下的子目录用add_subdirectory命令加进来的CMakelists.txt脚本片段 :#定义CASSDK位置if(NOT CASSDK_DIR) set( C原创 2016-07-12 15:46:14 · 52103 阅读 · 7 评论 -
cmake:eclipse和ultraedit对CMakeLists.txt的语法高亮支持
关于编辑器对cmake的脚本的支持,参见:https://cmake.org/Wiki/CMake_Editors_Support 列出了各类编辑器对cmake脚本的支持。对于eclipse我使用CMakeEd,我的eclipse版本是lunna,在线安装不成功(https://marketplace.eclipse.org/content/cmake-editor)。 改为从这里下载安装包(ht原创 2016-08-30 13:33:41 · 2592 阅读 · 1 评论 -
cmake:vs2015/MinGW静态编译leveldb
leveldb是google的开源项目(https://github.com/google/leveldb), 在linux下编译很方便,然而官方版本却没有提供在windows下的编译方式。还好,开源的世界热心人很多,同样在github上找到了cmake编译版本(https://github.com/bureau14/leveldb),有了cmake版本,windows下编译的问题就解决了一大半,下原创 2017-06-21 23:32:10 · 2233 阅读 · 0 评论 -
cmake:msvc编译第三方库时使用/MT静态库连接c/c++ runtime library
关于在cmake生成msvc工程时静态链接c/c++运行库的问题,很久以前写过一篇博客《cmake设置msvc的运行库(runtime library)塈指定openjpeg使用静态库》。当时的办法是在CMakeLists.txt中加一段代码将C_FLAGS_XXX,CXX_FLAGS_XXX等所有变量中的/MD替换成/MT ,就这样解决了问题。if(MSVC) # Us原创 2017-06-27 00:10:50 · 7569 阅读 · 7 评论 -
cmake: 使用jom实现msvc工程并发编译提高速度(-j)
msvc提供的nmake并没有并发编译功能(类似gcc make的-j参数指定并发编译的任务数), 而第三方工具jom(http://wiki.qt.io/Jom)解决了这个问题,jom可以像gcc 的make一样 通过-j参数指定并发编译,让cpu全速运行,可以大大提高编译速度,节省大型项目的编译时间。 cmake也支持jom编译,cmake 有一个名为”NMake Makefiles JOM原创 2017-06-28 21:43:30 · 6756 阅读 · 1 评论 -
cmake:msvc分别对不同的target使用不同的运行库选项(/MT或/MD)
很久以前写过一篇关于cmake下为msvc设置/MT的文章: cmake:msvc编译第三方库时使用/MT静态库连接c/c++ runtime library当时是为了解决用msvc编译时使用/MT连接static c library的问题。CMakeLists.txt中添加如下的代码,即可以将所有默认的C,CXX编译选项中的/MD替换成/MT.if(MSVC) ...原创 2018-04-17 13:49:58 · 3434 阅读 · 10 评论 -
cmake:DEBUG_POSTFIX 根据debug/release类型指定target的输出文件名
在用cmake生成工程文件(such as Makefile)编译项目的时候,有时我们希望debug/release生成的二进制文件在文件名上有区别: 比如对于target project1,在debug模式编译的dll,希望在Debug模式下生成的文件名为project1_d.dll,以与release模式下编译的project1.dll区别开。该怎么实现呢? (本文末尾有更新内容)...原创 2018-04-18 00:05:57 · 8539 阅读 · 3 评论 -
cmake:Cannot specify include directories for imported target
问题描述当使用INTERFACE选项调用target_include_directories命令向IMPORTED target添加include文件夹时会报如题的错误,过程描述:# 创建一个imported target MyLibadd_library(MyLib SHARED IMPORTED)set_property(TARGET MyLib PROPERTY IMPOR...原创 2018-04-26 09:50:21 · 8094 阅读 · 0 评论 -
cmake:用于查找libjpeg-turbo的module FindTurboJPEG.cmake
libjpeg-turbo的安装包没有提供用于CONFIG模式查找包(find_package)的cmake脚本,如果cmake脚本中要查找libjpeg-turbo库,就得自己写脚本。 于是我参照cmake 查找标准libjpeg库 的Module FindJPEG源码的写法实现了libjpeg-turbo的Module FindTurboJPEG.cmake。 为了更方便引用libjpeg...原创 2018-04-25 22:23:20 · 2279 阅读 · 1 评论 -
cmake:LINK : error LNK2001: 无法解析的外部符号 WinMainCRTStartup
正在设计的一个C/C++混合语言项目是用cmake来管理编译的,用cmake生成的一个Visual Studio工程(c++)在编译时报了个错: LINK : error LNK2001: 无法解析的外部符号 WinMainCRTStartup好是莫名其妙的问题,之前是没有这个问题的,反复查看了GIT提交记录,发现问题出在cmake脚本中 原本项目的定义是这样的,语言指定C,CXX...原创 2018-09-11 22:18:50 · 5970 阅读 · 0 评论 -
cmake error: includes target which requires target that is not in the export set,解决静态库的PRIVATE依赖导出问题
问题描述最近在使用 interface libraries时出了个小问题。 示例如下,我希望target not_exported只是作为fse_cas_static 的private类的依赖库内部使用,不希望在config file中导出对它的依赖。# 创建静态库add_library(fse_cas_static STATIC ${_SOURCE_FILES})# 创建inter...原创 2018-04-29 14:18:12 · 4598 阅读 · 1 评论 -
cmake:使用find_package查找libjpeg的静态库
我们知道简单的使用命令find_package可以查找指定的package.对于经常会用到的 jpeg库turbojpeg,可以用find_package(JPEG REQUIRED)来查找。find_package(JPEG REQUIRED)if(JPEG_FOUND) message(STATUS "JPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIR}") me...原创 2018-10-03 15:35:28 · 5290 阅读 · 1 评论 -
cmake:解决error LNK2005: void * __cdecl operator new(unsigned __int64) already defined in LIBCMTD.lib
当以/MT选项编译MFC项目时,会报下面的错误1>nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned __int64)" (??2@YAPEAX_K@Z) 已经在 LIBCMTD.lib(new_scalar.obj) 中定义1>nafxcwd.lib(原创 2018-10-10 16:34:04 · 12298 阅读 · 0 评论 -
cmake:macro,function中ARGV,ARGN参数的区别
cmake中的宏(macro)和函数(function)都支持动态参数变量ARGC记录传入的参数个数变量ARGV0,ARGV1,...顺序代表传入的参数变量ARGV则是一个包含所有传入参数的list变量ARGN也是一个包含传入参数的list,但不是所有参数,而是指macro/function声明的参数之后的所有传入参数写一个小程序就可以验证:# 定义一个宏,显式声明了两个参数hello...原创 2018-10-12 15:25:38 · 6556 阅读 · 1 评论 -
cmake:pkg_check_modules(FindPkgConfig)的新特性IMPORTED_TARGET
pkg-config提供了一个统一的接口查询安装库的编译相关信息。它允许程序员和安装脚本工作没有明确详细的库路径信息。和cmake相比,pkg-config是另一个独立的历史更悠久的library信息描述体系,cmake的FindPkgConfig Module的作用是调用pkg-config查找pkg-config格式的库信息.cmake 3.6版本以后用于查找pkg-config格式安装包...原创 2018-10-12 15:56:02 · 8831 阅读 · 1 评论 -
cmake:CMAKE_SYSTEM_PROCESSOR为空是怎么回事儿?
今天执行cmake创建Makefile的时候出了个怪事:CMAKE_SYSTEM_PROCESSOR的值为空反复测试到到了原因:我在执行cmake时加了参数-DCMAKE_SYSTEM_NAME=Linuxcmake . -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_SYSTEM_NAME=Linux根据cmake官方关于交叉编译的介绍: 《Cr...原创 2018-10-17 11:15:29 · 6599 阅读 · 0 评论 -
cmake:FindLIBCONFIG.cmake查找libconfig的脚本find_package脚本
libconfig 是一个用于读取,操作和编写结构化配置文件的库。cmake并没有为libconfig提供find_package脚本。所以自己撸一个,实现跨平台的查找libconfig库FindLIBCONFIG.cmake# - Find libconfig# - This module determines the libconfig library of the system# T...原创 2018-10-14 15:55:18 · 1029 阅读 · 3 评论 -
cmake/gcc:strip缩减程序体积
方法1cmake生成的Makefile中有一个target名为intall/strip可以将install的可执行程序执行strip,执行make help,就可以看到$ make helpThe following are some of the valid targets for this Makefile:... all (the default if no target is pr...原创 2018-10-20 14:14:48 · 12494 阅读 · 1 评论