CMakeList.txt |
您所在的位置:网站首页 › go语言可以写Linux脚本吗 › CMakeList.txt |
致每一个还坚持在互联网和软件行业的同路人。 最近有朋友问我为什么选择当程序员,我也不明白。可能是缺少社交能力,可能更喜欢心理上保存平静,可能是为了那份对于从无到有的沉浸感和满足感。 目录欢迎加入陈达书--C++交流群: Errrr113(非诚勿扰) 定义 PROJECT关键字 XXXX_BINARY_DIR 和 XXXX _SOURCE_DIR SET关键字 MESSAGE关键字 ADD_EXECUTABLE关键字 语法的基本原则 内部构建和外部构建 HELLO更像一个工程 ADD_SUBDIRECTORY指令 更改二进制的保存路径 安装 静态库和动态库的构建 动态库的版本号 安装共享库和头文件 使用外部共享库和头文件 DEBUG编译 定义cmake是一种高级编译工具,所有的操作系统都是通过编译CMakeList.txt来完成的,当多个人用不同的语言或者编译器开发同一个项目的时候,最终要输出一个可执行文件或者共享库的时候使用cmake很方便。 camke的下载网址:cmake不同版本下载地址 PROJECT关键字可以用来指定工程的名字和支持的语言,默认支持所有的语言。 project(XXXX) ===> 指定了工程的名字,并且支持所有语言 project(XXXX CXX) ===> 指定了工程的名字,并且支持的语言是C++ project(XXXX C CXX) ===> 指定了工程的名字,并且支持的语言是C 和 C++ XXXX_BINARY_DIR 和 XXXX _SOURCE_DIR_BINARY_DIR 和 _SOURCE_DIR它们都指向了当前的工作目录,当工程的名字发生改变时这两个变量的名字也会跟着改变。 使用 PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR SET关键字用来显示指定变量 SET(SRC_LIST main.cpp) ==> SRC_LIST变量就包含了main.cpp SET(SRC_LIST main.cpp demo1.cpp demo3.cpp demo1.h) ==> SRC_LIST变量就包含了main.cpp demo1.cpp demo3.cpp demo1.h 设置使用g++编译器 set(CMAKE_CXX_COMPILER "g++") 指定编译器 set(CMAKE_CXX_STANDARD 11) 添加c++11的支持,nation指定目标程序的cpu架构来进行程序优化 -O3优化等级 set(CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3") ===> native 就是相当于自检查cpu,-march是gcc优化选项,-Ox 这个参数只有在 cmake -DCMAKE_BUILD_TYPE=release时有效 版本号 set (XXXX VERSION 0.0.1) MESSAGE关键字向终端输出用户自定义的信息 主要包含三种信息: SEND_ERROR ==> 产生错误,生成编译过程中被跳过 STAUS ==> 输出前缀为一的信息 FATAL_ERROR ==> 立即终止所有cmake过程 message(STATUS "This is BINARY dir" $(PROJECT_BINARY_DIR)) message(STATUS "This is SOURCE dir" $(PROJECT_SOURCE_DIR)) ADD_EXECUTABLE关键字生成可执行文件 ADD_EXECUTABLE(XXX ${SRC_LIST}) ===> 生成可执行文件hello,源文件读取变量SRC_LIST中的内容 ADD_EXECUTABLE(XXX main.cpp) ===> 也可以直接填写 main.cpp 工程名和生成的可执行文件hello是没有任何关系 ==> 工程名和可执行 语法的基本原则变量使用${}方法取值,但是在IF控制语法中是直接使用变量名的 指令(参数1 参数2...)参数使用括号()括起来,参数之间使用空格或者分号分隔。 例如:ADD_EXECUTABLE(XXX main.cpp demo.cpp) 或者ADD_EXECUTABLE(XXX main.cpp demo.cpp) 指令是大小写无关的,参数和变量是大小写相关的 ==> 建立指令全部大写
语法注意事项: SET{SRC_LIST main.cpp}可以写成SET{SRC_LIST "main.cpp"} ==> 如果源文件名中含有空格,就必须要加双引号。 ADD_EXECUTABLE(hello main) => 后缀可以不写,会自动寻找.c和.cpp文件,最好同时存在main.cpp和main.c 内部构建和外部构建内部构建: 上述例子就是内部构建,他产生的临时文件特别多,不方便清理。 外部构建: 就会把生成的临时文件放到build目录下,不会对源文件源任何影响 推荐使用外部构建: 1.建立一个build目录,可以是任何地方,建立在当前目录下 2.进入build,运行cmake .. ==> 表示上级目录,你可以写CMakeLists.txt所在的绝对路径,生成的文件都在build目录下了 3.在build目录下,运行make来构建项目
使用外部构建 PROJECT_SOURCE_DIR ==> 指工程路径 PROJECT_BINARY_DIR ==> 编译路径 build目录的绝对路径 HELLO更像一个工程1.为工程添加一个子目录src,用来放置工程源代码 2.添加一个子目录dec,用来存放这个工程的文档 3.在工程目录添加文本文件 COPYRIGHT README ==> 描述项目的安装、编译方法 4.在工程目录添加一个 runhello.sh脚本,用来调用hello二进制 5.将构建后的目标文件放入构建目标的bin子目录 6.将doc目录的内容以及COPYRIGHT/README 安装到 /usr/share/doc/cmake . |---- build |---- CMakeList.txt |---- src |---- CMakeList.txt |---- main.cpp # ==> 外层CMakeLists.txt# PROJECT(CmakeList)# ADD_SUBDIRECTORY(src bin)# ==> src下的CMakeLists.txt# ADD_EXECUTABLE(hello main.cpp) 会生成很多中间文件,我们关注我们需要关注的部分就可以了 ADD_SUBDIRECTORY指令ADD_SUBDIRECTORY(source_dir [binary_dir] [EXECLUDE_FROM_ALL]) 1.这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。 2.EXECLUDE_FROM_ALL函数从将某个目录排除在外 ADD_SUBDIRECTORY(src bin) 1.将src子目录加入工程并指定编译输出(包含编译中间结果) 路径为bin目录 2.如果不进行bin目录的指定,那么编译结果(包括中间结果)都将存放在build 和 src下 上述没有指定bin的路径,其实我们可以通过更改二进制的保存路径来指定bin目录,不使用默认生成的路径(build中)。 更改二进制的保存路径SET 指令重新定义 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH变量来指定最终的目标二进制的位置。 SET{EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin} SET{LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib} 注:哪里要改变目标存放的路径,就在哪里加入上述的定义
一种是从代码编译后直接make install安装,一种是打包时指定目录安装。 指定目录安装: make install DESTDIR=/xxx/xxx ./configure -prefix=/xxx/xxx ------------------------------------------------------------------------------------------------------------------------- 使用CMAKE一个指令: INSTALL INSTALL的安装可以包括:二进制、动态库、静态库、文件、目录、脚本等 使用CMake一个新的变量: CMAKE_INSTALL_PREFIX ------------------------------------------------------------------------------------------------------------------------- 目录结构: . |__build |__CMakeList.txt |__COPYRIGHT |__doc | |__hello.txt |__README |__XXXX.sh |__src |__CMakeList.txt |__main.cpp -------------------------------------------------------------------------------------------------------------------------安装文件COPYRIGHT和README INSTALL(FILES COPYRIGHT README DESTINATION xxx/xxx/xxx/) FILES ====>文件 DESTINATION ===> 路径 1.可以写绝对路径 2.可以写相对路径,相对路径实际是: ${CMAKE_INSTALL_PREFIX}/ CMAKE_INSTALL_PREFIX 默认是 /usr/local/ cmake -DCMAKE_INSTALL_PREFIX=/usr 在cmake的时候指定CMAKE_INSTALL_PREFIX 安装脚本 INSTALL(PROGRAMS xxxx.sh DESTINATION bin) PROGRAMS: 非目标文件的可执行程序安装(比如脚本之类) 说明: 实际安装到的是 /usr/local/ ==> 默认路径是/usr/local 安装doc中的hello.txt 1.通过在doc目录构建CMakeList.txt,通过install下的file 2.直接通过在工程目录通过 INSTALL(DIRECTORY doc/ DESTINATION xxx/xxx/xxx) DIRECTORY后面连接的是所在Source目录下的相对路径 注意:abc和abc/有很大区别: 目录名不以/结尾: 将整个目录安装到目标路径 目录名以/结尾: 将整个目录中的内容安装到目标路径 任务: 1.建立一个静态库和动态库,提供HelloFunc函数供其他程序使用,HelloFunc向终端输出 Hello World 2.安装头文件与共享库 静态库和动态库的区别: 1.静态库的扩展名一般为 ".a" 或者 ".lib",动态库的扩展名一般为".so"或者".dll"2.静态库在编译时会直接整合到目标程序中,编译成功的可执行文件可独立运行3.动态库在编译时不会放到连接的目标程序中,即可执行文件无法单独运行 构建实例: . |--- build |--- CMakeLists.txt |--- lib |--- CMakeLists.txt |--- hello.cpp |--- hello.h 同时构建静态库和动态库 1.一种错误的示范:这种方式只会构建一个动态库,不会构建出静态库,虽然静态库.a ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC}) 2.修改动态库的名字,这样是可以的 ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) 3.但是在实际的开发过程中,我们往往希望静态库和动态库的名字相同 SET_TARGET_PROPERTIES ==> 这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和API版本 ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello") SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1) 的默认路径是 /usr/local 文件放到该目录下 INSTALL(FILES hello.h DESTINATION include/hello) 二进制、静态库、动态库安装都用TARGETS ARCHIVE 特指静态库, LIBRARY 特指动态库, RUNTIME 特指可执行目标二进制 准备一个项目:去调用上面生成的动态库 . |--- build |--- CMakeLists |--- src |--- CMakeLists.txt |--- main.cpp cmake -DCMAKE_BUILD_TYPE=debug .. cmake -DCMAKE_BUILD_TYPE=release .. |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |