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.pswp.cn/news/375745.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375745.shtml
英文地址,請注明出處:http://en.pswp.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;這些是在項目管理工具選擇或開發時需要面對和思考的一個問題。 傳統項目管理工具在團隊內部臭名昭著 項目管理工具當初都是為了項…