《PT0092_Linux下C++开发(四)-----计算机学习实战课件.pptx》由会员分享,可在线阅读,更多相关《PT0092_Linux下C++开发(四)-----计算机学习实战课件.pptx(15页珍藏版)》请在三一办公上搜索。
1、Linux下C+开发(四)动、静态库与安装操作,Linux下C+开发,本系列Linux下的C+开发,主要分为两大部分,第一部分讲解Linux下C+的开发流程及一些基础知识,第二部分讲解Cmake的使用,初步计划如下:1,Linux下C+的开发流程及基础知识介绍2,cmake简述及CMakeLists基本语句语法3,多目录工程4,动,静态库及安装操作5,模块的使用及自定义模块6,Linux下各种IDE介绍和对比今天主要给大家介绍的就是第二部分的第三节:动、静态库及安装操作,本系列Linux下的C+开发,主要分为两大部分,第一部分讲,安装操作,这里讲到的安装操作类似一种自动化的复制我们首先看一下本
2、次项目的结构,将工程项目中的各种类型的文件安装到指定的目录中去,将cmake/3/COPYRIGHT安装到cmake/install_dir/doc 将cmake/3/README安装到cmake/install_dir/doc 将cmake/3/doc/hello.txt安装到cmake/install_dir/doc将cmake/3/runhello.sh安装到cmake/install_dir/bin将输出的二进制文件也安装到cmake/install_dir/bin,安装操作这里讲到的安装操作类似一种自动化的复制将工程项目中的,安装操作,接下来看如何在CMakeLists.txt中具体
3、实现这些步骤,cmake_minimum_required(VERSION 2.6)PROJECT(demo3)MESSAGE(STATUS This is BINARY dir $demo3_BINARY_DIR)MESSAGE(STATUS This is SOURCE dir $demo3_SOURCE_DIR)#add executable fileADD_SUBDIRECTORY(./src)#set CMAKE_INSTALL_PREFIXSET(CMAKE_INSTALL_PREFIX /home/liqi/workspace/cmake/install_dir)MESSAGE(
4、STATUS CMAKE_INSTALL_PREFIX= $CMAKE_INSTALL_PREFIX)#install some filesINSTALL(PROGRAMS runhello.sh DESTINATION bin)INSTALL(DIRECTORY doc/ DESTINATION doc)INSTALL(FILES COPYRIGHT README DESTINATION doc),主目录的CMakeLists.txt,ADD_EXECUTABLE(hello hello.c)#set output pathSET(EXECUTABLE_OUTPUT_PATH $CMAKE_
5、BINARY_DIR/bin)#MESSAGE($EXECUTABLE_OUTPUT_PATH)INSTALL(TARGETS hello RUNTIME DESTINATION bin),src目录下的CMakeLists.txt,安装操作接下来看如何在CMakeLists.txt中具体实现,安装操作,CMAKE_INSTALL_PREFIX变量CMAKE_INSTALL_PREFIX变量类似于configure 脚本的 prefix常见的使用方法看 起来是这个样子: cmake -DCMAKE_INSTALL_PREFIX=/usr .如果没有额外定义,那么CMAKE_INSTALL_PR
6、EFIX变量默认为/usr/local DESTINATION定义了安装的路径如果路径以/开头,那么指的是绝对路径,这时候 CMAKE_INSTALL_PREFIX其实就无效了如果你希望使用CMAKE_INSTALL_PREFIX来 定义安装路径,就要写成相对路径,即不要以/开头那么安装后的路径就是 $CMAKE_INSTALL_PREFIX/,安装操作CMAKE_INSTALL_PREFIX变量,安装操作,INSTALL(TARGETS targets. ARCHIVE|LIBRARY|RUNTIME DESTINATION PERMISSIONS permissions. CONFIGUR
7、ATIONS Debug|Release|. COMPONENT OPTIONAL . ) 参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的 目标文件,可能是静态库、动态库、可执行二进制,INSTALL(FILES files. DESTINATION PERMISSION permissions. CONFIGURATIONS Debug|Release|. COMPONENT RENAME OPTIONAL) 可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路,安装操作 INSTALL(TARGETS targets.,安装操
8、作,INSTALL(PROGRAMS files. DESTINATION PERMISSIONS permissions. CONFIGURATIONS Debug|Release|. COMPONENT RENAME OPTIONAL) 非目标文件的可执行程序安装(比如脚本之类)安装后权限为: OWNER_EXECUTE, GROUP_EXECUTE, 和WORLD_EXECUTE,即755权限,INSTALL(DIRECTORY dirs. DESTINATION FILE_PERMISSIONS permissions. DIRECTORY_PERMISSIONS permission
9、s. USE_SOURCE_PERMISSIONS CONFIGURATIONS Debug|Release|. COMPONENT PATTERN | REGEX EXCLUDE PERMISSIONS permissions. .)PATTERN用于使用表达式进行过滤PERMISSIONS用于指定PATTERN过滤后的文件 权限。,INSTALL(SCRIPT CODE .) SCRIPT参数用于在安装时调用cmake脚本文件(也就是.cmake文件) CODE参数用于执行CMAKE指令,必须以双引号括起来。比如: INSTALL(CODE MESSAGE(Sample install m
10、essage.),安装操作INSTALL(PROGRAMS files.,动、静态库,动态库:动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在静态库:静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,本次示例工程文件结构如左图所示 hello.c与hello.h将被用来生成动态库和静态库并且将生成的库文件放到下面lib文件夹中,动、静态库动态库:动态库在程序编译时并不会被连接到目标代码中,#cmake versioncmake_minimum_required(VERSION 2.8.3)#project namePRO
11、JECT(demo4)#add subdirectoryADD_SUBDIRECTORY(library)#set prefixSET(CMAKE_INSTALL_PREFIX /home/liqi/workspace/cmake/install_dir)MESSAGE(STATUS CMAKE_INSTALL_PREFIX= $CMAKE_INSTALL_PREFIX),主目录下的CMakeLists.txt,#cmake version主目录下的CMakeLists.,#set source variableSET(LIBHELLO_SRC hello.c)#add executable#
12、ADD_EXECUTABLE(demo4 hello.h hello.c)#set output pathSET(LIBRARY_OUTPUT_PATH $PROJECT_BINARY_DIR/lib)#SET(EXECUTABLE_OUTPUT_PATH $PROJECT_BINARY_DIR/bin)#add libraryADD_LIBRARY(hello SHARED $LIBHELLO_SRC)ADD_LIBRARY(hello_static STATIC $LIBHELLO_SRC)#change static library propertySET_TARGET_PROPERTI
13、ES(hello_static PROPERTIES OUTPUT_NAME hello)#change CLEAN_DIRECT_OUPUT propertiesSET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)#add shared library version numberSET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVE
14、RSION 1)#install librariesINSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)#install include fileINSTALL(FILES hello.h DESTINATION include),library目录下的CMakeLists.txt,ADD_LIBRARY(libname SHARED|STATIC|MODULE EXCLUDE_FROM_ALL source1 source2 . sourceN)SHARED 动态库STATIC
15、静态库 MODULE 在使用dyld的系统有效,如果不支持dyld,则被当作SHARED对待EXCLUDE_FROM_ALL参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手 工构建,#set source variable library目录,GET_TARGET_PROPERTY(VAR target property) GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME) MESSAGE(STATUS “This is the hello_static OUTPUT_NAME:”$OUTPUT_VALUE)如果没有
16、这个属性定义,则返回NOTFOUND,SET_TARGET_PROPERTIES(target1 target2 . PROPERTIES prop1 value1 prop2 value2 .)这条指令可以用来设置输出的名称,对于动态库还可以用来指定动态库版本和API版本例如:SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME hello) SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(hello_stati
17、c PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1) VERSION指代动态库版本,SOVERSION指代API版本,GET_TARGET_PROPERTY(VAR target,Dynamic Link Library“Dll hell” 动态库新版本覆盖旧版本,但是却不兼容老版本 ()Linux 上的Dll ,叫shared library 它有三个名字1.共享库本身的文件名(real name),其通常包含版本号,比如libmath.so.1.
18、1.1234共享库的命名必须如 libname.so.x.y.z最前面使用前缀”lib”,中间是库的名字和后缀”.so”,最后三个数字是版本号。x是主版本号(Major Version Number),y是次版本号(Minor Version Number),z是发布版本号(Release Version Number)2.动态库的so-name( Short for shared object name),其是应用程序加载dll 时候,其寻找共享库用的文件名。其格式为lib + math+.so + ( major version number)其只包含major version numbe
19、r,换句话说,也就是只要其接口没有变,应用程序都可以用,不管你其后minor build version or build version。软连接(Symbol Link) ;readelf -d sharelibrary ; ldconfig3.共享库的连接名(link name),是专门为build 阶段连接而用的名字。这个名字就是lib + math +.so ,比如libmath.so。其是不带任何版本信息的。在共享库编译过程中,连接(link) 阶段,编译器将生成一个共享库及real name,同时将共享库的soname,写在共享库文件里的文件头里面。可以用命令 readelf -d
20、 sharelibrary 去查看。如用GCC的“-l”参数链接共享库libtXXX.so.3.8.1,只需要在编译器命令行指定 -l XXX 即可,省略了前缀和版本信息。编译器会根据当前环境,在系统中的相关路径(往往由-L参数指定)查找最新版本的XXX库。这个XXX就是共享库的“链接名”,Linux动态库的版本控制,Dynamic Link LibraryLinux动态库的版,动、静态库的使用,最后,我们来使用我们自己刚刚建立的库创建库与使用库可以在一个工程中进行在生成库的时候我们就可以添加一个test二进制文件并运行它来检测我们的库是否成功生成,动、静态库的使用最后,我们来使用我们自己刚刚
21、建立的库,INCLUDE_DIRECTORIES(/home/liqi/workspace/cmake/install_dir/include)LINK_DIRECTORIES(/home/liqi/workspace/cmake/install_dir/lib)#SET(LIB /home/liqi/workspace/cmake/install_dir/lib/libhello.so)ADD_EXECUTABLE(demo5 main.c)#MESSAGE(STATUS EXT_LIB= $LIB)#SET(EXECUTABLE_OUTPUT_PATH $CMAKE_BINARY_DIR/
22、bin)TARGET_LINK_LIBRARIES(demo5 hello.so),动、静态库的使用,cmake_minimum_required(VERSION 2.8.3)PROJECT(demo5)ADD_SUBDIRECTORY(src bin),主目录下的CMakeLists.txt,src目录下的CMakeLists.txt,LINK_DIRECTORIES(directory1 directory2 .) 这个指令非常简单,添加非标准的共享库搜索路径,比如,在工程内部同时存在共享库和可 执行二进制,在编译时就需要指定一下这些共享库的路径,TARGET_LINK_LIBRARIES(target library1 library2 .) 这个指令可以用来为target添加需要链接的共享库,本例中是一个可执行文件,但是同样可以用于为自己编写的共享库添加共享库链接,INCLUDE_DIRECTORIES(/home/liqi,动、静态库的使用,使用ldd指令,查看是否库文件链接成功了,动、静态库的使用使用ldd指令,查看是否库文件链接成功了,