库的制作和项目管理工具makefile\qmake\cmake

一 gcc编译器常用选项
 -E 预处理 -S编译 -c汇编 输入均为.c文件,输出分别为.i .s .o
 -std=standard 编译标准 如-std=c++11
 -g 编译调试
 -O 优化级别
 -Wwarm 指定警告级别,可以-Wall  -Wextra
 -I指定include目录,通常用于包含其他文件夹下头文件
 -L 指定链接库目录
 -D  编译时添加宏定义 用于ifdefine代码可选择性生效
 -U  取消宏定义 用于编译时某些c文件宏有定义,有些则没有
 -f 编译动态库时,使用-fpic
 -m 机器选项如-m64 -m32
 -o 指定输出文件,即指定编译后可执行文件的文件名
 infile 输入文件列表
 
二 利用gcc编译动态库和静态库
 1、制作动态库时必须加参数-fpic -shared,生成的动态库需要指定为libxxx.so文件
 使用动态库时,动态库的名字为xxx,前后的lib和.so需要省略
 例如:gcc -fpic -shared func.c -o libfunc.so
 
 链接动态库时,即使动态库在当前目录也需要加参数-L指定链接库目录
 例如:gcc main.c -L. -lfunc
 
 如果程序编译时链接了动态库,运行时也需要加载动态库,这里提供两种方法
 第一,运行前输入命令export LD_LIBRARY_PATH=动态库所在目录
 这种方法每次重启linux都需要重新导入
 
 第二,将动态库放入系统默认的库目录/usr/lib
 这种方法重启系统不需要重新导入,但会导致系统库目录越来越大
 
 最好的解决方案是将用到的动态库放入系统配置文件,每次开机自动加载
 
 动态库并不会打包到程序中,而是利用共享映射,多个程序共享同一个库文件
 优点是节约内存,精简程序,便于程序升级,维护方便
 
 2、静态库
 静态库制作利用打包命令
 ar rcs libtest.a a.o b.o
 rcs是指参数-r -c -s,libxxx.a是表示静态库,库名为xxx
 打包库时需要用汇编文件.o进行打包
 
 链接库时,如果动态库静态局同名,默认优先链接动态库
 如果要链接静态库,需要使用-static
 如:gcc a.c -lfunc -static
 
 使用以下命令可以指定某些库静态链接,某些库动态链接
 -wl,-Bstatic -lfunc1 -wl,-Bdynamic -lfunc2
 
 静态库会直接打包到程序中,优点是程序运行速度快,但升级不方便,程序占用空间较大
 
三 makefile
 makefile为项目管理工具,通常为makefile或者Mikefile文件
 makefile有三个要素:目标、依赖和命令
 整个makefile只有一个终极目标,可以有多个子目标
 当在命令行使用make xxx的时候,表示生成子目标,直接make生成终极目标
 
 依赖表示目标需要依赖哪些文件来生成,命令表示具体生成的过程
 
 可以使用变量
 如果使用 := 那么立即赋值
 如果使用 = 那么使用时才赋值
 建议使用 := 不要使用=号
 比如:target := libxxx.so 表示target这个变量就表示动态库libxxx.so
 使用的时候需要$(target)
 
 可以使用函数,也需要使用$ 
 比如,查找所有.c文件
 src:=(wildcard ./*.c) 或者
 通过shell函数,去执行shell命令
 srcs := $(shell ls *.c)
 srcs := $(shell find -name "*.c")
 
 再比如,把所有.c替换成.o
 obj := $(patsubst ./%.c ,./%.o $(src)) 或者
 objs := $(srcs:.c=.o)
 gcc -MM命令可以查询.c文件所依赖的文件
 通常可以通过引入.d文件来使得头文件加入依赖
 比如,利用deps来使头文件加入依赖
 deps := $(srcs:.c=.d) 具体使用看下面案例
 
 -f  强制执行
 .PHONY:clean声明伪目标
 -rm -的作用是如果命令失败忽略  继续向下执行
 
 可以通过include包含其他子makefile。
 比如自己手写一个makefile规则def.mk,该文件包含生成的依赖所需条件
 在主makefile中可以直接用include包含该文件,则规则被包含
 include def.mk
 使用-开头表示如果def.mk不存在,那么也继续执行
 -include def.mk
 可以包含子目录的makefile进行同时编译
 make -C sub  执行子目录sub的makefile
 
 内置变量
 CC = g++(默认为gcc,可以手动赋值)
 CPPFLAGS预编译时需要的参数,如- I
 CFLAGS 编译时需要使用的参数 -Wall -g -cc即gcc
 LDFLAGS 链接库使用的选项,如-L -l
 环境变量可以用在Make中,但是不建议用
 环境变量和本地变量名字相同时,本地变量覆盖环境变量
 Make的自动变量
 $^ 它表示所有的依赖
 $@ 表示目标
 $< 表示第一个依赖
 $?是比Makefile更加新的文件,也就是最近修改文件
 比如:
 file_in_a = $(shell find a -type f)
 Makefile: $(file_in_a)
  cp $? b
  touch Makefile
 缺省规则
 如果.o没有指定依赖,那么.o默认有一个依赖
 %.o: %.c
      $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
 默认的依赖可以被覆盖
 案例一:
 target := libxxx.so
 all: ${target}
 -include $(deps)
 %.d: %.c
  gcc -MM $< > $@
 $(target): ${objs}
  $(CC) $^ -fpic -shared -o $@
 clean:
  rm *.o *.so *.d
 install:
  cp ${target} /usr/lib
 uninstall:
  rm /usr/lib/${target}
 test:
  echo $(CC)
  echo src file is: $(srcs)
 
 案例二:
 src = $(wildcard *.c)
 obj = $(patsubst %.c, %.o, $(src))
 soktfile = $(wildcard *.socket)
 all: server client
 server: server.o
  gcc server.o -o server -Wall
 client: client.o
  gcc client.o -o client -Wall
 %.o:%.c
  gcc -c $< -Wall
 .PHONY: clean all
 clean:
  -rm -rf server client $(obj) $(soktfile)
  
四 qmake
 1 在需要编译的文件夹输入 qmake -project 会生成qmake-当前目录.pro
 2 输入qmake 会自动生成Makefile文件
 3 输入make 会自动生成qmake-当前目录文件  该文件就是可执行文件
 
五 cmake
 1 安装cmake
  Ubuntu系统,通过以下命令安装cmake
  sudo apt-get install cmake
 
 2 使用cmake需要编辑的是CMakeLists.txt文件
 
 3 最简单的hello文件的实现
  cd到当前目录,编辑CMakeLists.txt如下:
  project(当前目录)
  add_executable(hello.bin main.c)
  //main.c为代码 hello.bin为生成的可执行程序名
  随后退出CMakeLists.txt
  创建一个build目录(非必须,但是惯例),用于保存中间文件与生成的程序
  进入build,cmake ..
  然后make,则可在当前目录(build)生成hello.bin
 
 4 可以使用变量
  通过set设置变量,通过${}取值
  set(src main.c func1.c func2.c)
  add_executable(HelloWorld.bin ${src})
 
 5 可以使用函数
  (1)搜索指定目录所有源码
  aux_source_directory(搜索目录 存入的变量) 
  使用该函数前必须要加:cmake_minimum_required(VERSION 3.7)
  aux_source_directory(. src)
  aux_source_directory(./sub src) //搜索子目录
  (2)链接动态库
  target_link_libraries(可执行程序名) //可执行程序名可以使用变量
  需要放在该语句之后add_executable
 
  (3)包含头文件
  include_directories(头文件目录1 头文件目录2 头文件目录3 ...)
  //也可以多次include
  
  (4)设置库目录
  link_directories()同上
 6  编译库文件
  不适用add_executable而使用add_library()和set_target_properties
  add_library(${target} SHARED ${srcs})
  add_library(hello_a STATIC ${srcs}) //若不加中间参数,默认生成静态库
  //只需指定编译的库名xxx,程序会自动生成libxxx.so或者libxxx.a
 7  定义宏
 add_definitions(-A -B ...)
 通常在源代码添加ifdefine来灵活使用宏
 
 8  编译选项
 支持CFLAGS,CXXFLAGS
 
 9  进阶
 http://blog.chinaunix.net/uid-24512513-id-3196376.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值