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

        <projectname>_BINARY_DIR 和 <projectname>_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}/<DESTINATION>

 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) 

安装共享库和头文件

<prefix>的默认路径是  /usr/local

文件放到该目录下

INSTALL(FILES hello.h DESTINATION include/hello)

二进制、静态库、动态库安装都用TARGETS

ARCHIVE 特指静态库,  LIBRARY 特指动态库, RUNTIME 特指可执行目标二进制

 

使用外部共享库和头文件

准备一个项目:去调用上面生成的动态库

.
|--- build
|--- CMakeLists
|--- src
       |--- CMakeLists.txt
       |--- main.cpp

 

 

DEBUG编译

cmake -DCMAKE_BUILD_TYPE=debug ..

cmake -DCMAKE_BUILD_TYPE=release ..

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
当涉及到 Vue DHTMLX-Gantt 导出 Excel 的保姆级完整教程时,以下是一步一步的指南: 1. 确保您的项目中已经安装了 Vue 和 DHTMLX-Gantt。如果尚未安装,请使用以下命令进行安装: ```bash npm install vue dhtmlx-gantt ``` 2. 在您的 Vue 组件中引入所需的库和样式: ```javascript import 'dhtmlx-gantt'; import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'; ``` 3. 创建一个 Vue 组件,并在模板中添加一个 Gantt 图表和一个按钮: ```html <template> <div ref="ganttContainer" style="width: 100%; height: 600px;"></div> <button @click="exportData">导出 Excel</button> </template> <script> import * as XLSX from 'xlsx'; import FileSaver from 'file-saver'; export default { mounted() { const ganttContainer = this.$refs.ganttContainer; gantt.init(ganttContainer); // 设置 Gantt 图表的配置和数据 // 示例数据 const tasks = [ { id: 1, text: '任务1', start_date: '2022-01-01', duration: 5, progress: 0.5 }, { id: 2, text: '任务2', start_date: '2022-01-06', duration: 4, progress: 0.2 }, // 其他任务... ]; gantt.parse({ data: tasks }); }, methods: { exportData() { const gantt = this.$refs.ganttContainer.$gantt; const tasks = gantt.getDatastore('task').getItems(); // 将任务数据转换为 Excel 数据格式 const data = tasks.map((task) => { return { id: task.id, text: task.text, start_date: task.start_date, duration: task.duration, progress: task.progress, }; }); // 创建 Excel 文件 const worksheet = XLSX.utils.json_to_sheet(data); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Gantt Data'); const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const excelData = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 下载 Excel 文件 FileSaver.saveAs(excelData, 'gantt_data.xlsx'); }, }, }; </script> <style> /* 可选的样式 */ </style> ``` 4. 在上述示例代码中,需要注意以下部分: - 在 `mounted` 钩子中,使用 `gantt.init(ganttContainer)` 初始化 Gantt 图表,并根据您的需求设置其配置和数据。 - `exportData` 方法用于将 Gantt 图表数据导出到 Excel。确保在 `exportData` 方法中的 `this.$refs.ganttContainer.$gantt` 是对 Gantt 图表组件的正确引用。 - 点击 "导出 Excel" 按钮时,将会生成一个名为 `gantt_data.xlsx` 的 Excel 文件,其中包含了 Gantt 图表的数据。 这就是使用 Vue DHTMLX-Gantt 导出 Excel 的保姆级完整教程。希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

存钱买房的陈一言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值