CMake實踐(3)


一,本期目標

[sun@localhost t3]$ cat README
t3:靜態庫(.a)與動態庫(.so)構建
    任務:1,建立一個靜態庫和動態庫,提供HelloFunc函數供其他程序編程使用
             HelloFunc向終端輸出Hello World字符串
          2,安裝頭文件與共享庫
使用方法
到<path_to>/t3/build,執行:
cmake -DCMAKE_INSTALL_PREFIX=/home/TOM/tmp ..
make
make instal

二,目錄結構:

[sun@localhost t3]$ tree ../t3/
../t3
├── build
├── CMakeLists.txt
├── lib
│   ├── CMakeLists.txt
│   ├── hello.cpp
│   └── hello.h
└── README

三,CMakeList.txt

[sun@localhost t3]$ cat CMakeLists.txt

PROJECT(HELLOLIB)
cmake_minimum_required(VERSION 2.6)
ADD_SUBDIRECTORY(lib)
[sun@localhost t3]$ cat lib/CMakeLists.txt
SET(LIBHELLO_SRC hello.cpp)

#1)注意: 下面2句不能同時出現,因為target名稱是唯一的,如果想要得到相同名稱的動態庫和靜態庫
#必須借助於SET_TARGET_PROPERTIES
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
#ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})


#2)注意:有了以下兩句,我們就可以同時得到同名的動態庫和靜態庫了,
#      但是你會發現libhello.so卻消失了,因為cmake在構建一個新的target時,
#      會嘗試清理掉其它使用這個名字的庫,所以在構建libhello.a時,就會清理掉libhello.so
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

#3)要避免同名不同類型的庫覆蓋,需要再借助於SET_TARGET_PROPERTIES指令
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

#4)增加動態庫版本號
#   按照規則,動態庫是應該包含一個版本號的,我們看一下系統的動態庫,一般情況是:
#   libhello.so.1.2
#   libhello.so->libhello.so.1
#   libhello.so.1->libhello.so.1.2
#   以下命令中,VERSION指代動態庫版本,SOVERSION指代API版本
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

#5)安裝共享庫和頭文件
#   hello的共享庫安裝到<prefix>/lib目錄
#   hello.h安裝到<prefix>/include/hello目錄
INSTALL(TARGETS hello hello_static
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)

INSTALL(FILES hello.h DESTINATION include/hello)



#COMMAND: ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXECLUDE FROM_ALL]
#             source1 source2 ... sourceN)
#注意:不需要寫全libhello.so,只需要填寫hello即可,cmake系統會自動為你生成libhello.X
#       類型有3種:SHARED(動態庫),
#                  STATIC(靜態庫),
#                  MODULE(在使用dyld的系統有效,否則被當作SHARED對待)
#       EXCLUDE_FROM_ALL:這個庫不會被默認構建,除非有其它的組件依賴或者手工構建

#COMMAND: SET_TARGET_PROPERTIES(target1 target2 ...
#                               PROPERTIES prop1 value1 prop2 value2 ...)
#定義:用來設置輸出的名稱,對於動態庫,還可以用來指定動態庫版本和API版本。
#備注:其它對應的指令是:GET_TARGET_PROPERTIES(VAR target property)
#      如:GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
#          MESSAGE(STATUS "This is the hello_static OUTPUT_NAME:"${OUTPUT_VALUE})
#          如果沒有這個屬性定義,則返回NOTFOUND


四,運行結果

[sun@localhost t3]$ cd build/
[sun@localhost build]$ cmake ..
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /opt/gcc/bin/gcc
-- Check for working C compiler: /opt/gcc/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/gcc/bin/c++
-- Check for working CXX compiler: /opt/gcc/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sun/program/cmake_practice/t3/build
[sun@localhost build]$ make
Scanning dependencies of target hello
[ 50%] Building CXX object lib/CMakeFiles/hello.dir/hello.cpp.o
Linking CXX shared library libhello.so
[ 50%] Built target hello
Scanning dependencies of target hello_static
[100%] Building CXX object lib/CMakeFiles/hello_static.dir/hello.cpp.o
Linking CXX static library libhello.a
[100%] Built target hello_static


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM