linux基础

来源:互联网 发布:淘宝退货率太高 编辑:程序博客网 时间:2024/05/29 14:51
gcc(GNU C Compiler)编译器的作者是Richard Stallman。
支持多种语言如C、C++、Java、Pascal、Ada、COBOL语言等。
gcc是一种可移植的编译器,支持多种硬件平台。gcc不仅仅是个本地编译器,它还能跨平台交叉编译。
gcc是GNU Compiler Collection的缩写。
gcc是按模块化设计的,可以加入新语言和新CPU架构的支持
gcc是自由软件
预处理(Pre-Processing):-E 处理头文件、宏等语句,最终生成的是 .i的临时文件。
编译(Compiling):-S 将c语言文件编译成汇编语言的文件,最终生成的是 .s文件。
汇编(Assembling):-c 将汇编语言的文件汇编成二进制文件,最终生成的是 .o文件。
链接(Linking):-o 将生成的二进制文件和各种库文件进行链接,最终生成 可执行文件。重定位
-o 还可直接生成可执行文件。作用是产生目标。
-Wall
-Werror

使用外部库
静态库与共享库
生成静态库
生成动态库

在使用c语言和其他语言进行程序设计的时候,
我们需要头文件来提供对常数的定义和对系统及
库函数调用的声明。

库文件是一些预先编译好的函数集合,那些函数
都是按照可重用的原则编写的。它们通常由一组
互相关联的用来完成某项常见工作的函数构成。比如
用来处理屏幕显示情况的函数(ncurses库)和数据库
访问例程(dbm库)等。

使用库的好处:模块化、可重用性高、可维护性

头文件和库文件位置:
/usr/include及其子目录地下的include文件夹
/usr/local/include及其子目录底下的include文件夹
/usr/lib
/usr/local/lib

静态库与共享库的区别:

*.a是静态库,在程序编译链接的时候把库的代码链接到
可执行文件中。程序运行的时候将不再需要静态库。占用内存。可执行文件大。现在已经使用的很少。

*so或*.sa是动态库-共享库,程序在运行的时候才去链接共享库的代码
多个程序共享使用库的代码。内存占用少。

一个与共享库链接的可执行文件仅仅包含它用
到的函数入口地址的一个表,而不是外部函数
所在目标文件的整个机器码

在可执行文件开始运行以前,外部函数的机器
码由操作系统从磁盘上的该共享库中复制到
内存中,这个过程称为动态链接(dynamic linking)

共享库可以在多个程序间共享,所以动态链接
使得可执行文件更小,节省了磁盘空间。操作
系统采用虚拟内存机制允许物理内存中的一份
共享库被要用到该库的所有进程共用,节省了内存和磁盘空间。


使用外部库 (-l选项)

生成静态库:
库是一个归档文件。将*.o文件打包就可生成*.a文件
ar 是GNU归档工具,rcs表示(replace and create)
ar rcs libhello.a hello_fn.o

gcc -c hello_fn.c生成hello_fn.o文件
两种生成办法
gcc -Wall main.c libhello.a -o main -static
gcc -Wall -L. main.c -o main -lhello
          指定库文件目录     库文件名称
gcc -Wall -L./tmp -I./tmp main.c -o main -lhello -static
                  查找头文件
gcc -Wall -L./tmp -Iinclude main.c -o main -lhello -static

库搜索路径
C_INCLUDE_PATH、LIBRARY_PATH
vi ~/.bash_profile添加export LIBRARY_PATH=/yyd/mycode/tmp
执行配置文件让它生效:. ~/.bash_profile
没有指定-L选项,gcc -Wall  -Iinclude main.c -o main -lhello它也可以执行。

从左到右搜索-I -L指定的目录。
由环境变量指定的目录
由系统指定的目录

环境变量
vi  /etc/profile 修改
source /etc/profile 使能

静态库与共享库同时存在是优先使用共享库

生成共享库
shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
示例:gcc -shared -fPIC hello.o –o libhello.so
使用共享库
编译选项
l:链接共享库,只要库名即可(去掉lib以及版本号)
L:链接库所在的路径.
示例:
gcc main.o -o main –L. -lhello
./main
./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
ldd main查看
ldd main
  linux-gate.so.1 =>  (0x0080a000)
  libhello.so => not found
  libc.so.6 => /lib/libc.so.6 (0x00b88000)
  /lib/ld-linux.so.2 (0x00b6b000)
 
linux为我们提供了两种解决方法:
1.可以把当前路径加入/etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。
2.把当前路径加入环境变量LD_LIBRARY_PATH中
当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位
置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
 /etc/ld.so.conf
export命令:设置或显示环境变量。
静态库和动态库文档:
http://wenku.baidu.com/link?url=3CEPYG531W3wmY3DQbO5bNYf6SGeFZaQGz1SnsVOatRWsyD2RP_oM8LoL_Z6_M96KV1eV4IKffk86dO6H3VTEWurcAWqK847kM_b4DjQaRO
linux下动态库静态库使用:
http://blog.csdn.net/liujwcool1/article/details/8179698

1、拷贝.so文件到系统共享库路径下
    一般指/usr/lib
2、更改LD_LIBRARY_PATH
3、ldconfig
 配置ld.so.conf,ldconfig更新ld.so.cache


Makefile
make与Makefile介绍
Makefile基本规则
简单的Makefile编写
Make自动化变量
Makefile编译多个可执行文件

利用 make 工具可以自动完成编译工作。这些工作包括:
如果仅修改了某几个源文件,则只重新编译这几个源文件;
如果某个头文件被修改了,则重新编译所有包含该头文件的源文件。
利用这种自动编译可大大简化开发工作,避免不必要的重新编译。

make是一种工具
make 工具通过一个称为 Makefile 的文件来完成并自动维护编译工作。
Makefile文件描述了整个工程的编译、连接等规则。

TARGET … : DEPENDENCIES …
        COMMAND
        …
目标(TARGET)程序产生的文件,如可执行文件和目标文件;目标也可以是要执行的动作,如clean,也称为伪目标。
依赖(DEPENDENCIES)是用来产生目标的输入文件列表,一个目标通常依赖于多个文件。

命令(COMMAND)是make执行的动作(命令是shell命令或是可在shell下执行的程序)。注意:每个命令行的起始字符必须为TAB字符!
如果DEPENDENCIES中有一个或多个文件更新的话,COMMAND就要执行,这就是Makefile最核心的内容

touch main.c 生成多个文件
Makefile中
.PHONY:clean
clean:
        rm -f main main.o add.o sub.o
 .PHONY是伪目标。
假如不想让执行的命令显示出来时,在命令的最前面加上@ 例:@rm -f main main.o add.o sub.o

makefile变量:
选项名      作用
 $@          规则的目标文件名
 $<          规则的第一个依赖文件名
 $^          规则的所有依赖文件列表

Makefile编译多个可执行文件
模式规则
%.o:%.c
后缀规则
.c.o:

例:
.PHONY:clean all
bin = 01test 02test
all:$(bin)
%o:%c
        gcc -Wall -c $< -o $@
01test:01test.o
        gcc -Wall $< -o $@
02test:02test.o
        gcc -Wall $< -o $@
clean:
        rm -f *.o $(bin)
专业Makefile:
.PHONY:clean all
bin = 01test 02test
CC=gcc
CFLAGS=-Wall
all:$(bin)
%.o:%.c
        $(CC) $(CFLAGS) -c $< -o $@
01test:01test.o
        $(CC) $(CFLAGS) $< -o $@
02test:02test.o
        $(CC) $(CFLAGS) $< -o $@
clean:
        rm -f *.o $(bin)


make常用内嵌函数
多级目录Makefile

make常用内嵌函数:
函数调用
   $(function arguments)
$(wildcard PATTERN)
当前目录下匹配模式的文件
例如:src=$(wildcard *.c)
$(patsubst PATTERN,REPLACEMENT,TEXT)
模式替换函数
例如:$(patsubst %.c,%.o,$src)
等价于$(src:.c=.o)
shell函数
执行shell命令
例如:$(shell ls –d */)

多级目录Makefile:
CC      = gcc   
CFLAGS  =-Wall -g
BIN     = main  
SUBDIR  = $(shell ls -d */) # */表示模式匹配
ROOTSRC = $(wildcard *.c)
ROOTOBJ = $(ROOTSRC:%.c=%.o)
SUBSRC  = $(shell find $(SUBDIR) -name '*.c')
SUBOBJ  = $(SUBSRC:%.c=%.o)
$(BIN):$(ROOTOBJ) $(SUBOBJ)
        $(CC) $(CFLAGS) -o $(BIN) $(ROOTOBJ) $(SUBOBJ)
.c.o:
        $(CC) $(CFLAGS) -c $< -o $@
clean:
        rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)
自己修改的例子:
.PHONY:clean
CC=gcc
CFLAGS=-Wall
bin=main
SUBDIR=$(shell ls -d */)
ROOTSRC=$(wildcard *.c)
ROOTOBJ=$(ROOTSRC:%.c=%.o)
SUBSRC=$(shell find $(SUBDIR) -name '*.c')
SUBOBJ=$(SUBSRC:%.c=%.o)

$(bin):$(ROOTOBJ) $(SUBOBJ)
        $(CC) $(CFLAGS) $^ -o $@
%.o:%.c
        $(CC) $(CFLAGS) -c $< -o $@
clean:
        rm -f *.o $(bin) $(SUBOBJ)

0 0
原创粉丝点击