以下內容為本人實習期間學習筆記!!參考了網上的許多教程,共享大家,歡迎交流。
動態庫和靜態庫(共享庫)
不同點:代碼被載入的時刻不同
靜態庫的代碼在編譯過程中已經被載入可執行程序,因此體積比較大,程序運行時不再需要靜態庫
動態庫的代碼編譯時不會鏈接到目標代碼中,運行時才被載入,程序運行時還需要動態庫存在
庫的編譯:無論是靜態庫還是動態庫,都是.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_DEBUG
和CMAKE_C_FLAGS_DEBUG
中的字符串生成Makefile
=Release時,使用變量CMAKE_CXX_FLAGS_RELEASE
和CMAKE_C_FLAGS_RELEASE
OPTION
:提供用戶可以選擇的選項
OPTION(OPTION_VAR "注釋"[初始值])
,初始值選項為ON
或OFF
,未提供則為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_CHECK
和BOOST_REQUIRE_EQUAL
是Boost提供的預定義宏,用于驗證代碼輸出
4、Boost的一整套的測試工具,基本上可以說是用于驗證表達式的宏;
主要有3個類別:BOOST_WARN、BOOST_CHECK、BOOST_REQUIRE
;
BOOST_CHECK
和BOOST_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
還不是很完善。。會持續完善的。。。