linux平台开发自学笔记(三)-代码编译

  1. 云栖社区>
  2. 博客>
  3. 正文

linux平台开发自学笔记(三)-代码编译

leonwei 2014-09-12 17:42:00 浏览899

linux和window编代码其实大致上是差不多的,不过在一些概念上还有差别,比如使用的库不一样,编译工具不一样,shell不一样,库的链接方式也不一样,这里做个简要的总结


1.库

window上有两种,动态库和静态库,动态库一般需要在程序编译时定义一些符号(.lib文件),然后运行时依赖.dll文件动态载入代码的

静态库则在编译时就直接把(静态库的.lib文件)编译链接进去。

当然window动态库的使用还有其他的方式,比如编译时不去导入符号,而是运行时使用dllimport等接口现场导入某个动态dll

使用动态库的好处是减少代码体积,在一个机器上同其他程序共享库的代码


在linux上分这两种库,静态库一般是.a文件,动态库是.so 文件,编译时使用gcc *.a(*.so) 就可以把库加进去,或者使用gcc -lm 意味着加入libm.a或者libm.so,默认会从默认路径寻找库,也可以通过gcc -L来制定库所在的文件夹。这里注意的是linux下面的动态库只需要一个.so就可以了,不需要windows上的符号导入。如果用了.so那么在运行程序时必须保证能找的到编译时用的那个so,要么放入默认文件夹,要么放在app同一个路径下


2.gcc,cc/gcc是linux下面常用的一个c编译器(编译c++代码时就变成了g++),gcc可以将一些c/cpp/o文件编译成 o/so/可执行文件的程序,通常的用法如下:

gcc -c .c 将源文件编译成obj文件

gcc -o app .a .so .o 将obj文件和库编成可执行文件


此外

gcc  -I 在编译时指定include文件的搜索文件夹

g  -L 在编译时指定lib文件的搜索文件夹


生成.a静态库

ar   crv .a .o .o (其实.a文件在linux上就好比很多.o文件的压缩包)

生成.so动态库

gcc -shared -fPIC -o .so .o


可以同 ldd app来查看某个可执行文件需要依赖那些动态库,类似于window上vs带的dependency工具


3.make

make其实是linux一个具有多种处理文件过程的工具,也是编译大型工程的重要工具,在windows上,我们使用vs等ide编译一个工程很容易,但是vs为我们隐藏了一些细节,比如先生成了哪些obj文件,又是按照怎样的顺序连接?每次更改一个h文件的时候那些cpp需要重新编译?当然这是大型IDE的好处,在linux下面就需要自己去定义这些东西,这就需要make工具。


make工具需要有makefile,makefile定义了一个工程的组织形式,如make会找到当前路径下叫做Makefile的文件进行执行,如果没有,就需要通过make -f ***来指导去运行那个makefile了


makefile我认为是解决两件事:第一,尽量少的在改动代码后重新编译,所以是定义文件间的依赖;第二,定义没个文件的gcc编译规则。所以makefile基本由这两部分组成


dependency

rules(rules必须以tab开头,每行的结尾存在空格也可能导致错误)

以下是一个样本

首先这里的最上层(依赖关系的跟节点)的release clean 称为target,默认make制定会只make第一个target,可以制定make clean执行其中某个target,还可以make all 执行在all里面定义的target,#代表注释

#all:release clean

release:.o .o #这里说明最跟处的(一般是app本身啦)依赖两个.o文件
    gcc -o target .o .o #(用gcc说明怎样生成这个app)
.o: .c .h .h#说明这个.o依赖某几个代码文件
  gcc -c .c #用gcc说明这个.o文件如何生成

clean:
 -rm .o .o .o #将几个obj文件清除


当定义lib文件时,只用依赖不用rule,如
mylib.a:mylib.a(a.o) mylib.a(b.o) 说明mylib.a从a.o和b.o生成

使用某个子文件夹里的make生成的库
mylib.a:
    (cd subdir;$(MAKE)) 

宏:

MACRONAME=value #定义
 $(MACRONAME) #使用