C/C++编译、测试须知、须会,CMake、Boost等

以下内容为本人实习期间学习笔记!!参考了网上的许多教程,共享大家,欢迎交流。

动态库和静态库(共享库)

不同点:代码被载入的时刻不同

静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大,程序运行时不再需要静态库

动态库的代码编译时不会链接到目标代码中,运行时才被载入,程序运行时还需要动态库存在

库的编译:无论是静态库还是动态库,都是.o文件创建的。
静态库:
1、先通过gcc编译成.o文件
gcc -o hello.o -c hello.c
2、生成静态库.a文件
ar cqs libHello.a hello.o
3、链接
gcc main.c libHello.a -o Out1

动态库:
动态库的名字一般是libxxx.so,动态函数库在编译的时候并没有编译进代码中,生成的可执行文件比较小,动态函数库的升级比较方便。

创建动态库的方法一般采用C语言编译器的-G或者-shared选项,或者直接使用工具ld创建。
-shared:该选项指定生成动态链接库,不使用该标志外部程序无法连接,相当于一个可执行文件
-fpic:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,二不能达到真正代码段共享的目的。
-L:表示要连接的库在当前目录中
-ltest:编译器查找动态链接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

1、生成中间目标文件.o
g++ -fpic -c test.cpp
2、根据中间文件创建动态库文件.so
g++ -shared -o libtest.so test.o
3、调用动态库
g++ -o Tout main.cpp ./libtest.so

gcc编译,如果是c++文件,直接将gcc改成g++

1、gcc -c test.c ---->生成.o目标代码

2、gcc -o test test.c ---->生成bin可执行文件

3、gcc test.c ---->生成a.out可执行文件
常用参数:
1、-E;指示编译器仅对输入文件进行预处理,使用该选项时预处理器的输出被送到标准输出,而不是存储在文件里。

2、-S;指示编译器为c代码产生汇编语言文件后停止编译,汇编文件的缺省扩展名是.s

3、-c;仅把源代码编译为目标代码。缺省时GCC建立的目标代码文件有一个.o的拓展名

4、-o(小写);编译选项为将产生的可执行文件指定文件名

5、-O(大写);对源代码进行基本优化,主要进行跳转和延迟退栈两种优化
-O0:不做优化;-O1:默认优化;-O2:除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整;-O3:包括循环展开和其他一些与处理特性相关的优化工作。

6、-l-L;指定程序要链接的库,-l参数紧接着就是库名。
如数学库,它的库名为m,它的库文件名是libm.so
如果要用一个第三方提供的库,要先把这个.so文件拷贝到/usr/lib里,编译时加上参数,-l库名。
如果要用库里的函数,还需要与该库配套的头文件。
放在/lib/usr/lib/usr/local/lib里的库直接用-l参数就能链接,如果没有在这三个目录里,需要用-L
如常用的X11的库,它放在/usr/X11R6/lib目录下,编译时要用-L/usr/X11R6/lib -lX11

7、-Wall;打印出gcc提供的警告信息
-w;关闭所有警告信息;-v;列出所有编译步骤

交叉编译:
交叉编译通俗地讲就是在一中平台上编译出能运行在体系结构不同的另一种平台上。
交叉编译用到的编译器叫交叉编译器,做本地编译的叫本地编译器。
使用方法跟本地的gcc差不多,但有一点特殊的是,必须用-L和-l指定编译器用系统的库和头文件。

cmake简单语法规则:

[官方文档]:[https://cmake.org/cmake/help/cmake2.4docs.html]
[中文对照]:[http://www.cnblogs.com/52php/p/5684588.html]
1、变量使用${}方式取值,在IF控制语句中直接使用变量名。
2、指令(参数1 参数2)参数使用括弧括起,参数之间使用空格或分好分开。
3、指令大小写无关,参数和变量大小写相关。

外部编译:
1、需要为任何子目录建立一个CMakeLists.txt
2、ADD_SUBDIRECTORY指令:ADD_SUBSIRECTORY(source_dir [binary_dir][EXCLUDE_FROM_ALL]),用于向当前工程添加存放源文件的子目录,并可有指定中间二进制和目标二进制存放的位置。
3、通过SET命令重新定义编译输出。
EXECUTABLE_OUTPUT_PATH指定最终的目标二进制的位置。
LIBRARY_OUTPUT_PATH指定最终共享库目录。
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
在外部编译中PROJECT_BINARY_DIR指的是外部编译所在目录。

PROJECT(project_name):指定项目的名称

CMAKE_MINIMUM_REQUIRED(VERSION 3.13):限定CMake的最低版本要求

AUX_SOURCE_DIRECTORY(. DIR_SRCS):将当前目录中的源文件名称赋值给变量
AUX_SOURCE_DIRECTORY(<dir> <variable>)

ADD_EXECUTABLE(main ${DIR_SRCS}):指示需要编译的源文件和要生成的可执行文件名

ADD_SUBDIRECTORY(src):添加一个子目录

TARGET_LINK_LIBRARIES(main Test):指明可执行文件main需要连接一个名为Test的链接库

ADD_LIBRARY(Test ${DIR_TEST1_SRCS}):将该目录中的源文件编译为共享库

查找并使用其他程序库
FindlibNAME.cmake:NAME是函数库名称,如查找头文件db_cxx.h和链接库libdb_cxx.so
命名为:Findlibdb_cxx.cmake

PROJECT(main)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(CMAKE_SOURCE_DIR .)
SET(CMAKE_MODULE_PATH ${CMAKE_ROOT}/Modules ${CMAKE_SOURCE_DIR}/cmake/modules) 
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE(main ${DIR_SRCS})
FIND_PACKAGE( libdb_cxx REQUIRED)
MARK_AS_ADVANCED(
LIBDB_CXX_INCLUDE_DIR
LIBDB_CXX_LIBRARIES)
IF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)
#如果LIBDB_CXX_INCLUDE_DIR和LIBDB_CXX_LIBRARIES都被赋值MESSAGE(STATUS "Found libdb libraries")INCLUDE_DIRECTORIES(${LIBDB_CXX_INCLUDE_DIR})MESSAGE( ${LIBDB_CXX_LIBRARIES} )TARGET_LINK_LIBRARIES(main ${LIBDB_CXX_LIBRARIES}18 )
ENDIF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)

FIND_PACKAGE:查找库文件,命令执行后,CMake会到变量CMAKE_MODULE_PATH指示
的目录中查找文件Findlibdb_cxx.cmake并执行。

debug版本和release版本:

debug版本的项目生成的可执行文件需要有调试信息并且不需要进行优化
release版本的不需要调试信息但需要优化

在gcc/g++中通过编译时的参数来决定,优化成都调到最高需要设置参数-O3,最低-O0不做优化
添加调试信息-g -ggdb

CMake中变量CMAKE_BUILD_TYPE取值:Debug、Release、RelWithDebInfo、MinSizeRel

=Debug时,CMake使用变量CMAKE_CXX_FLAGS_DEBUGCMAKE_C_FLAGS_DEBUG中的字符串生成Makefile

=Release时,使用变量CMAKE_CXX_FLAGS_RELEASECMAKE_C_FLAGS_RELEASE

OPTION:提供用户可以选择的选项
OPTION(OPTION_VAR "注释"[初始值]),初始值选项为ONOFF,未提供则为OFF

通过OPTION(OPTION_VAR "" OFF)设置,则IF(OPTION_VAR)FALSE

IF语法:常用的是字符串比较
1、看字符串是否定义过:

IF(DEFINED STR_VAR)/IF(NOT DEFINED STR_VAR)
ELSE()
ENDIF()

2、字符串比较

IF(${STR_VAR} STREQUAL "ON")
ELSE()
ENDIF()

cmake使用流程:

CMakeLists.txt----->cmake----->Makefile----->make

cmake [options] <path-to-source>

boost test工具

1、
BOOST_AUTO_TEST_SUITE表示测试套件的开始
BOOST_AUTO_TEST_SUITE_END表示测试套件的结束
各个测试放在两个宏之间

2、
BOOST_AUTO_TEST_CASE定义单元测试

eg:

BOOST_AUTO_TEST_SUITE(stringtest)BOOST_AUTO_TEST_CASE(test1){mystring s;BOOST_CHECK(s.size()==0);
}BOOST_AUTO_TEST_SUIT_END()

3、单元测试的基本思想是使用Boost提供的宏来测试各个类特性。
BOOST_CHECKBOOST_REQUIRE_EQUAL 是Boost提供的预定义宏,用于验证代码输出

4、Boost的一整套的测试工具,基本上可以说是用于验证表达式的宏;
主要有3个类别:BOOST_WARN、BOOST_CHECK、BOOST_REQUIRE
BOOST_CHECKBOOST_REQUIRE之间的区别:前者即使断言失败,测试仍会进行,后者则认为是很严重的错误,当BOOST_REQUIRE失败时,代码不会继续执行。

5、检查函数和类方法,最简单的方法是创建一个新测试

BOOST_AUTO_TEST(functionTest1){BOOST_REQUIRE(myfunc1(99,'A',6.2)==12);myClass o1("hello world!\n");BOOST_REQUIRE(o1.memoryNeeded()<16);
}

6、浮点数比较
需要包含头文件:
#include<boost/test/floating_point_comparsion.hpp>
用到的宏:

BOOST_WARN_CLOSE_FRACTION
BOOST_CHECK_CLOSE_FRACTION
BOOST_REQUIRE_CLOSE_FRACTION

用法:
BOOST_CHECK_CLOSE_FRACTION(left-value,right-value,tolerance-limit);
tolerance-limit:精度要求,公差要求
BOOST_CHECK_CLOSE_FRACTION宏的左值和右值必须是同一种类型。
eg:

#define BOOST_TEST_MODULE floatingTest
#include<boost/test/included/unit_test.hpp>
#include<boost/test/floating_point_comparison.hpp>
#include<cmath>BOOST_AUTO_TEST_SUITE(test)BOOST_AUTO_TEST_CASE(test){float f1=123.43;float result=sqrt(f1);BOOST_CHECK_CLOSE_FRACTION(f1,result*result,0.0001);
}BOOST_AUTO_TEST_SUITE_END()

7、在一个文件中包含多个测试套件
可以在一个文件中包含多个测试套件,每个测试套件必须有一对宏。
在运行回归测试时,用预定义的--log_level=test_suite选项生成的输出很详细。

8、框架测试
代码入口点必须是名为:init_unit_test_suite的例程

#define BOOST_TEST_MODULE MasterTestSuite
#include<boost/test/included/unit_test.hpp>
using boost::unit_test;test_suite*
init_unit_test_suite(int argc,char* argv[]){test_suite* ts1=BOOST_TEST_SUITE("test_suite1");ts1->add(BOOST_TEST_CASE(&test_case1));ts1->add(BOOST_TEST_CASE(&test_case2));test_suite* ts2=BOOST_TEST_SUITE("test_suite2");ts2->add(BOOST_TEST_CASE(&test_case3));ts2->add(BOOST_TEST_CASE(&test_case4));framework::master_test_suite().add(ts1);framework::master_test_suite().add(ts2);return 0;
}

测试套件通过:BOOST_TEST_SUITE宏创建,通过add方法把所有的测试套件添加到主测试套件中。

单元测试通过:BOOST_TEST_CASE宏创建,通过add方法添加到测试套件中。

不建议把单元测试直接加到主测试套件中。

主测试套件:master_test_suite 方法属于:boost::unit_test_framework命名空间的一部分,它在内部实现了一个单实例对象。
使用BOOST_TEST_CASE宏创建的单元测试以函数指针作为输入参数。

9、装备
测试装备(test fixture)是指在执行测试之前设置一个环境,在测试完成时清除它。
宏:BOOST_FIXTURE_TEST_CASE(testname,F)

使用全局装备:BOOST_GLOBAL_FIXTURE(<Fixture Name>)

http2:超文本传输协议2.0

还不是很完善。。会持续完善的。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# DataTable去除重复,极其简便、简单

其中sourceDT是获取到的一个DataTable类型的集合对象 去重复使用方式&#xff1a; 实例化一个DataView对象 假设为dv&#xff0c;直接dv.ToTable()即可&#xff0c;ToTable中可为&#xff08;true,"用于判断重复的列"&#xff09;&#xff0c;比如图中所示&#xff0…

【转】C++类中对同类对象private成员访问

私有成员变量的概念&#xff0c;在脑海中的现象是&#xff0c;以private关键字声明&#xff0c;是类的实现部分&#xff0c;不对外公开&#xff0c;不能在对象外部访问对象的私有成员变量&#xff0e; 然而&#xff0c;在实现拷贝构造函数和赋值符函数时&#xff0c;在函数里利…

MySQL 导出命令

mysqldump --no-defaults -u root -p dbname > c:\www\test.sql windows 下使用。转载于:https://www.cnblogs.com/chenshuo/p/4646070.html

ubuntu16.04编译boost for Android(boost 1.65)

下载boost源码 在官网下载指定版本的源码 http://www.boost.org/users/history/ 编译boost源码 1.进入源码目录执行./bootstrap.sh生成编译工具 2.编辑project-config.jam文件,替换如下内容 # define platform name of ndk import os ; if [ os.name ] CYGWIN || [ os.na…

Jquery获取select,dropdownlist,checkbox下拉列表框的值

jQuery获取 Select选择的Text和Value:语法解释&#xff1a;1. $("#select_id").change(function(){//code...}); //为Select添加事件&#xff0c;当选择其中一项 时触发2. var checkText$("#select_id").find("option:selected").text(); //获…

maven2 + tomcat6 + eclipse集成配置

转载&#xff1a;http://wenku.baidu.com/view/d64147c676eeaeaad1f330d4.html?review /*maven2 tomcat6 eclipse集成配置maven的配置环境变量M2_HOME maven主目录环境变量path maven主目录/binapache-maven/conf/setting.xml文件1、新建maven本地仓库文件夹apache-maven2…

定位pure virtual method called问题

我是在进行boost test的时候遇到了这样的一个问题&#xff0c;最后问题定位到测试用例中&#xff0c;测试的工程以及单元测试的代码是之前的&#xff0c;没有开发完&#xff0c;我实习的时候leader让我完善一下测试框架&#xff0c;添加一下测试代码。 目标机是Android&#x…

环形矩阵

1.逆时针 代码&#xff1a; 1 // huanxingjz.cpp : Defines the entry point for the console application.2 //3 4 #include "stdafx.h"5 #include <stdio.h>6 #include <iostream>7 #include "windows.h"8 #define MAX 409 using namespace …

检查MySQL主从数据一致性

未公布转载于:https://www.cnblogs.com/cuizhipeng/p/4646489.html

统计文件里有多少个字符(only a simple cpp)

通过重定向读取文件内容&#xff0c;并检测其中有多少字符&#xff0c;包括空格&#xff0c;但tap键可能统计结果不同。 #include<iostream>int main(int argc,char *argv[]){using std::cin,std::cout,std::endl;cout<<"Usage:"<<argv[0]<<…

Winsock网络编程笔记(4)----基本的理论知识

前面的笔记记录了Winsock的入门编程&#xff0c;领略了Winsock编程的乐趣。。但这并不能算是掌握了Winsock&#xff0c;加深理论知识的理解才会让后续学习更加得心应手。。因此&#xff0c;这篇笔记将记录一些有关Winsock的基本理论知识&#xff0c;由于是一篇笔记&#xff0c;…

30分钟学会使用grunt打包前端代码

http://www.cnblogs.com/yexiaochai/p/3603389.html转载于:https://www.cnblogs.com/wuxiang/p/4647280.html

简单shell:删除五日之前的日志文件

曾经在某公司面试的时候被问到了类似的问题。 假设在logs文件夹存放了许多日志文件 比如&#xff1a;20190204.log、20190205.log、20190206.log。。。 我们要删除特定日期之前的日志 在这里展示的是使用shell指令中的find指令完成操作 首先看一下find指令的命令格式&#xf…

Method Swizzle黑魔法,修改 ios 系统类库方法(转载)

一般来说&#xff0c;系统提供的方法已经足够开发了&#xff0c;但是有的时候有些需求用普通方法不好做。 如&#xff1a;在所有的viewcontroll 的viewwillappear&#xff1a;方法之前打个log 你可能会这么做&#xff1a; 1. 建一个uiviewcontroll 父类&#xff0c;重写viewwil…

win10无法开启夜间模式

在学校的时候没感觉&#xff0c;一进公司发现电脑还是需要设置一下护眼的&#xff0c;但是在设置的时候却遇到夜间模式无法开启的问题。 首先在左下角搜索设备管理器 找到显示适配器 查看显示器设备状态 如果设备图标上有黄三角感叹号则说明该设备驱动有问题&#xff0c;需要…

Linux LVM学习总结——扩展卷组VG

Linux服务器由于应用变更或需求的缘故&#xff0c;有可能出现分区空间不足的情况&#xff0c;此时往往需要进行扩容&#xff08;要增加分区的空间&#xff09;&#xff0c;而采用LVM的好处就是可以在不需停机的情况下可以方便地调整各个分区大小。如下所示&#xff0c;分区/u05…

【液晶模块系列基础视频】1.3.iM_TFT30模块简介

【液晶模块系列基础视频】1.3.iM_TFT30模块介绍 技术论坛&#xff1a;http://www.eeschool.org 博客地址&#xff1a;http://xiaomagee.cnblogs.com 官方网店&#xff1a;http://i-board.taobao.com 银杏科技 GINGKO TECH. 保留权利&#xff0c;转载请注明出处 本次教学视频介…

C++控制向文件中写入浮点数的格式

有时会遇到向文件中写入一定格式的浮点数&#xff0c;为了对齐美观&#xff0c;常常采用控制小数点后的位数并用0补齐缺少的位数的方法。 #include <iostream> #include <iomanip> #include <fstream> using namespace std;int main(){double pi3.14;ofstre…

项目管理工具到底应该为谁服务?

项目管理工具到底应该为谁服务&#xff1f;为管理者&#xff0c;还是为了团队&#xff1b;为了管理报表&#xff0c;还是为了协作需求&#xff0c;这些是在项目管理工具选择或开发时需要面对和思考的一个问题。 传统项目管理工具在团队内部臭名昭著 项目管理工具当初都是为了项…