C++服务器框架开发11——编译调试1/cmake学习

这篇具有很好参考价值的文章主要介绍了C++服务器框架开发11——编译调试1/cmake学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。
其教学视频见:[C++高级教程]从零开始开发服务器框架(sylar)

上一篇:C++服务器框架开发10——日志系统1~9代码

目前进度

学习到第6个视频的00:59,由于不了解编译,这次先学习下cmake。下图是CMakeLists.txt中的内容。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

ubuntu下的cmake学习

参考自文章1
“CMake是一个跨平台的编译(Build)工具, 不同平台之间的编译方式遵循不同的规则,彼此不通用。因此 Cmake被提出,他统一了一套规则, 来描述所有平台的编译过程。
它允许开发者编写一种平台无关的 CMakeLists.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。”
以下内容基本上都是学习的文章1。

简单样例

C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
在文件目录下创建这两个文件,内容如下:
main.c,输出一个字符串。

#include <stdio.h>

int main(void)
{
	printf("Hello World\n");

	return 0;
}

CMakeLists.txt,其中各行的意思都有进行注释说明。

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo
project (demo)
# 将名为 main.c 的源文件编译成一个名称为 main 的可执行文件
add_executable(main main.c)

在该目录下打开一个终端,执行cmake ./得到makefile。
执行过程:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
执行后目录下的文件:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
执行make进行编译。
执行过程:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
执行后目录下多了一个main的可执行文件。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
运行main看看效果:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
如果想重新生成,可以先执行make clean来删除已有的main文件。

同一目录下多个源文件

上面的例子是只有一个源文件的,如果有多个的话,如下:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

main.c调用调用testFunc.h里声明的函数func()。
main.c:

#include <stdio.h>

#include "testFunc.h"

int main(void)
{
	func(100);

	return 0;
}

testFunc.h:

/*
** testFunc.h
*/

#ifndef _TEST_FUNC_H_
#define _TEST_FUNC_H_

void func(int data);

#endif

testFunc.c:

/*
** testFunc.c
*/

#include <stdio.h>
#include "testFunc.h"

void func(int data)
{
	printf("data is %d\n", data);
}

CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)
# 将名为 main.c 和testFunc.c的源文件编译成一个名称为 main 的可执行文件
add_executable(main main.c testFunc.c)

cmake 和make:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
运行:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
如果有很多源文件,这种方法就不太方便。可以使用aux_source_directory(dir var),这个命令将目录dir下的所有源文件存储在变量var中。
例子:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
main.c:

#include <stdio.h>

#include "testFunc.h"
#include "testFunc1.h"

int main(void)
{
	func(100);
	func1(200);

	return 0;
}

testFunc1.c:

/*
** testFunc1.c
*/

#include <stdio.h>
#include "testFunc1.h"

void func1(int data)
{
	printf("data is %d\n", data);
}

testFunc1.h:

/*
** testFunc1.h
*/

#ifndef _TEST_FUNC1_H_
#define _TEST_FUNC1_H_

void func1(int data);

#endif

CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)
#把当前目录下的源文件存放到变量SRC_LIST里
aux_source_directory(. SRC_LIST)
# 将SRC_LIST里的源文件编译成一个名称为 main 的可执行文件
add_executable(main ${SRC_LIST})

cmake 和make,并执行:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
如果不想把所有源文件都进行编译,可以用set来指定想要编译的源文件,对应的CMakeLists.txt可以修改为如下:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)
#把当前目录下的源文件存放到变量SRC_LIST里
set( SRC_LIST
	 ./main.c
	 ./testFunc1.c
	 ./testFunc.c)
# 将SRC_LIST里的源文件编译成一个名称为 main 的可执行文件
add_executable(main ${SRC_LIST})

不同目录下多个源文件

假设文件目录如下:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
修改CMakeLists.txt

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)
#由于main.c中include了两个.h文件,所以需要添加头文件的搜索路径
include_directories (test_func test_func1)
#把两个目录下的源文件分别存放到变量SRC_LIST和SRC_LIST1里
aux_source_directory (test_func SRC_LIST)
aux_source_directory (test_func1 SRC_LIST1)
# 将SRC_LIST里的源文件编译成一个名称为 main 的可执行文件
add_executable(main ${SRC_LIST} ${SRC_LIST1})

其中的include_directories (test_func test_func1)作用已经在注释里了。

正式一点的组织结构

src:源文件目录
include:头文件目录
build:生成的对象文件
bin:可执行文件。
结构调整如下:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)
#添加并构建子目录src
add_subdirectory(./src)

其中的add_subdirectory(src)指定src为源文件的存放位置,camke时回去src目录进行编译。
src/CMakeLists.txt:


#添加头文件的搜索路径
include_directories (../include)
#把源文件存放到变量SRC_LIST里
aux_source_directory (. SRC_LIST)
# 将SRC_LIST里的源文件编译成一个名称为 main 的可执行文件
add_executable(main ${SRC_LIST} )
#设置存放可执行文件的位置
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

其中set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)把存放可执行文件的位置设置为工程根目录下的bin目录。

为了让生成的对象文件放在build里,需要再build目录下打开终端,然后执行cmake ..,接着make
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
另一种方法,可以把子目录src中的cmakelists内容放到外层目录中来,只用一个camkelists。如下:
CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)

#添加头文件的搜索路径
include_directories (./include)
#把源文件存放到变量SRC_LIST里
aux_source_directory (./src SRC_LIST)
# 将SRC_LIST里的源文件编译成一个名称为 main 的可执行文件
add_executable(main ${SRC_LIST} )
#设置存放可执行文件的位置
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

build目录下cmake ../, 然后make,最后执行。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

动态库和静态库的编译控制

目录结构如下
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
把生成的库放在lib里。

CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)

#把文件testFunc.c存放到变量SRC_LIST里
set (SRC_LIST ${PROJECT_SOURCE_DIR}/testFunc/testFunc.c)

#生成库,库名字为testFunc_shared,设置为SHARED(动态库,不设置的话默认为静态),源文件为SRC_LIST
add_library (testFunc_shared SHARED ${SRC_LIST})
#生成库,库名字为testFunc_static,设置为STATIC(静态库,不设置的话默认为静态),源文件为SRC_LIST
add_library (testFunc_static STATIC ${SRC_LIST})

#设置动态库testFunc_shared文件名称为libtestFunc.so
set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
#设置静态库testFunc_static文件名称为libtestFunc.a
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")

#设置库文件的输出路径为./lib
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

add_library: 生成动态库或静态库。
set_target_properties: 设置最终生成的库的名称。
LIBRARY_OUTPUT_PATH: 库文件的默认输出路径。

build目录下cmake ../, 然后make
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
查看子目录lib
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

对库进行链接

重新构建如下工程,并把上一小节的生成的库放到./testFunc/lib下。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
main.c:

#include <stdio.h>

#include "testFunc.h"

int main(void)
{
    func(100);
    
    return 0;
}

testFunc.h:

/*
** testFunc.h
*/

#ifndef _TEST_FUNC_H_
#define _TEST_FUNC_H_

void func(int data);

#endif

CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)

#设置可执行文件的输出路径为./bin
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#把文件main.c存放到变量SRC_LIST里
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)
# 添加头文件的搜索路径
include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)
#在指定目录./testFunc/lib查找制定库testFunc
find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)
#将SRC_LIST里的源文件编译成一个名称为 main 的可执行文件
add_executable (main ${SRC_LIST})
#把目标文件与库文件进行链接
target_link_libraries (main ${TESTFUNC_LIB})


find_library: 在指定目录下查找指定库。
target_link_libraries: 把目标文件与库文件进行链接。

build目录下cmake ../, 然后make,最后执行。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

查看可执行文件使用了那些库readelf -d ../bin/main
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

添加编译选项

有时编译程序时想添加一些编译选项,如-Wall-std=c++11等,就可以使用add_compile_options来进行操作。
这里可以去看原文章的简单示例。

添加控制选项

如果想要在编译代码时只编译一些指定的源码,可以使用cmake的option命令。

本来要生成多个bin或库文件,现在只想生成部分指定的bin或库文件

如下结构:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
main1.c:

// main1.c
#include <stdio.h>

int main(void)
{
    printf("hello, this main1\n");
    
    return 0;
}

main2.c:

// main2.c
#include <stdio.h>

int main(void)
{
    printf("hello, this main2\n");
    
    return 0;
}

CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)
#设置一个option,名称为MYDEBUG,提示为"enable debug compilation",第3个参数的默认值是OFF。
option(MYDEBUG "enable debug compilation" OFF)
#设置存放可执行文件的位置
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#添加并构建子目录src
add_subdirectory(./src)

./src/CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)

#将源文件main1.c编译成一个名称为 main1 的可执行文件
add_executable(main1 main1.c)
#如果MYDEBUG为NO则将源文件main2.c编译成一个名称为 main2 的可执行文件
if (MYDEBUG)
    add_executable(main2 main2.c)
else()
    message(STATUS "Currently is not in debug mode")    
endif()

build目录下cmake ../, 然后make,最后查看bin目录。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习

对于同一个bin文件,只想编译其中部分代码(使用宏来控制)

结构如下:
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
main.c:

#include <stdio.h>

int main(void)
{
#ifdef WWW1
    printf("hello world1\n");
#endif    

#ifdef WWW2     
    printf("hello world2\n");
#endif

    return 0;
}

CMakeLists.txt:

# 指定所需 CMake 的最低版本
cmake_minimum_required (VERSION 2.8)
# 项目的名称 demo  
project (demo)

#设置存放可执行文件的位置
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#设置一个option,名称为WWW1,提示为"print one message",第3个参数的默认值是OFF。
option(WWW1 "print one message" OFF)
#设置一个option,名称为WWW2,提示为"print another message",第3个参数的默认值是OFF。
option(WWW2 "print another message" OFF)

#使用add_definitions()函数控制代码的开启和关闭
if (WWW1)
    add_definitions(-DWWW1)
endif()

if (WWW2)
    add_definitions(-DWWW2)
endif()
#将源文件main.c编译成一个名称为 main 的可执行文件
add_executable(main main.c)

只想编译WWW1里的内容:
build目录下cmake ../ -DWWW1=ON -DWWW2=OFF, 然后make,最后执行。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
只想编译WWW2里的内容:
build目录下cmake ../ -DWWW1=OFF -DWWW2=ON, 然后make,最后执行。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
编译WWW1和WWW2里的内容:
build目录下cmake ../ -DWWW1=ON -DWWW2=ON, 然后make,最后执行。
C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
:每次重新编译时,记得把build和bin中的文件删掉,否则build中的文件会影响下次编译,比如我第一次编译设置了WWW1,如果我没有删除build中文件,那么如果我第二次编译时没设置WWW1,WWW1将是上次编译时的设置。

这是我对cmake的所有学习记录,学习资料来自https://blog.csdn.net/whahu1989/article/details/82078563。这篇文章非常详细,我基本上理解清楚了cmake的基本用法。

回顾图1

C++服务器框架开发11——编译调试1/cmake学习,分布式服务器开发,c++,服务器,学习
set(CMAKE_VERBOSE_MAKEFILE ON)是显示原始编译信息,用于定位链接报错。
set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function")是编译选项设置,具体可以看这两篇文章:2和3。
add_dependencies(test sylar)是因为,编译可执行文件test时需要链接依sylar,而sylar也是通过编译得到的。所以设置这个后,当检测到依赖库sylar还没编译时,会先编译依赖库,然后再编译test。

这次笔记时隔很久,一是其他事情耽搁了,二是camke原先根本不会,三是这个笔记有点长。文章来源地址https://www.toymoban.com/news/detail-563748.html

到了这里,关于C++服务器框架开发11——编译调试1/cmake学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++服务器框架01_日志系统01

    sylar/log.h

    2024年02月12日
    浏览(50)
  • Goland连接服务器/虚拟机远程编译开发

    SSH用于与远程服务器建立连接 Settings - Tools - SSH Configurations 添加新的ssh连接,Host为ip地址,Username为用户名,认证方式这里选择密码验证 全部填完后可以点击Test Connection测试连接是否成功 Deployment用于构建本地与远程服务器的路径映射 Settings - Build,Execution,Deployment - Deployment 添

    2024年02月06日
    浏览(54)
  • C++高性能服务器网络框架设计与实现

    这篇文章将从两个方面来介绍,一个是服务器中的基础的网络通信部件;另外一个是,如何利用这些基础通信部件整合成一个完整的高效的服务器框架。注意:本文以下内容中的客户端是相对概念,指的是连接到当前讨论的服务程序的终端,所以这里的客户端既可能是我们传

    2024年02月04日
    浏览(54)
  • C++服务器框架02_日志系统02_logger

    sylar/log.h sylar/log.cpp

    2024年02月12日
    浏览(43)
  • C++服务器框架03_日志系统03_appender

    sylar/log.h sylar/log.cpp

    2024年02月13日
    浏览(82)
  • Linux下C++轻量级WebServer服务器 框架梳理

    WebServer是一个很好的入门级C++项目,因为它涉及到了方方面面,不仅可以提高编程能力,还包括了操作系统、计算机网络、数据库等方面的知识,所以我很推荐大家去入手这个项目。说细一点这个项目包含系统编程、日志系统、线程池、网络知识、并发模型等实现,但是很多

    2024年03月15日
    浏览(81)
  • 微信小程序开发者工具真机调试和预览连接本地服务器

    网上参考了很多方法只有这个方法能解决本地服务器在微信开发者工具预览或者真机调试的连接,话不多说看图。 win+R,CMD输入ipconfig查看本地电脑服务器地址 微信开发者工具里设置代理 js代码的地址对应IPv4 地址 最后你的wifi网络要和手机上的网络一致,不然真机调试或者预

    2024年02月11日
    浏览(103)
  • 从零开始实现一个C++高性能服务器框架----环境变量模块

    此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善 项目地址:https://gitee.com/lzhiqiang1999/server-framework 项目介绍 :实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括

    2024年02月02日
    浏览(55)
  • 从零开始实现一个C++高性能服务器框架----Hook模块

    此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善 项目地址:https://gitee.com/lzhiqiang1999/server-framework 项目介绍 :实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括

    2023年04月09日
    浏览(101)
  • 从零开始实现一个C++高性能服务器框架----Socket模块

    此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善 项目地址:https://gitee.com/lzhiqiang1999/server-framework 项目介绍 :实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括

    2023年04月08日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包