Linux下编译环境配置和搭建

配置安装虚拟机和Ubuntu系统:

虚拟机安装:

VMware Workstation版本:vmware-workstation-full-9.0.2-1031769

安装前请大家切记BIOSVT功能,不开的话安装Ubuntu 64bit 是不允许的。(设置安装64bit系统注意事项)

开启方式:Bios -> Security -> System Security -> enable VT

开启后就可以安装VM并自行破解。

注意:要先开启VT开安装VM,先安装VM再开启VT的话是不行的。

Unbuntu安装

版本:ubuntu-12.04.2-desktop-amd64.iso

注意:建议下载上面的版本,因为不同版之间的差异可能会引起一些不同问题。

选择64位是因为Google Android 的源码编环境译默认是要在64bit系统上跑的,虽然可以修改mk文件让它可以在32bit系统上跑,但是比较麻烦且网上的修改方法都比较老,找不到适合Android 4.X 的修改方法。


常用命令:
切换到root用户:(默认的配置的root和安装系统的密码是一样的,修改命令:sudo passwd root)
技术分享    
技术分享
技术分享

linux和window有两个共享的方式:
samba和VMTool共享方式
技术分享


GCC编译器&GCC编译过程:
技术分享
GCC的编译流程分为四个步骤:
四个步骤操作:生产相应的代码工作对应硬件设备
1:预处理gcc -e test.c o test.i(生产预处理代码)宏定义展开,去掉注释,条件编译,头文件(宏,类型定义,枚举声明,内联)cpp(预处理器)
2:编译gcc -s test.i o test.s(生产汇编代码)
汇编文件(规范性,语法检查)cc1(编译器)
3:汇编gcc -c test.s o test.o(生产目标代码)
重定位目标文件as(汇编器)
4:链接gcc     test.o o test(生产可执行代码)
./test
重定位文件与相关库文件链接(符合解析重定位)ld(链接器)
ps:用wc命令比较两代码;wc test.c test.o

GDB调试工具&调试流程
1:首先使用gcc对test.c进行编译,注意一定要加上选项‘-g‘ 
2:#gcc -g test.c -o test
3:gdb test
4:调试流程时的基本命令;
查看文件:(gdb)l
查看变量值:(gdb)p n 
设置断点:(gdb)b 6
查看断点情况:(gdb)info b
运行代码:(gdb)r
单步运行:(gdb)n;(gdb)s
恢复程序运行:(gdb)c
帮助:(gdb)help [command]
5:Gdb的使用切记点;
在gcc编译选项中一定要加入‘-g;
只有在代码处于“运行”或“暂停”状态是才能查看变量值;
设置断点后程序在指定行之前停止;
ps:
gdb设置断点与恢复命令 
技术分享
技术分享

Makefile编写总结:
基本实例:
CC=g++
CPPFLAGS=-Wall -g  #(Wall W一定要大写)
BIN=main
OBJS=main.o add.o sub.o  #(可以通过+=添加新的值如 main =+ test2.o)
$(BIN):$(OBJS)
$(CC) $(CPPFLAGS) $^ -o $@
%.o:%cpp
$(CC) $(CPPFLAGS) -c  $< -o $@
.PHONY:clean
 clean:
 rm -f *.0 $(BIN)
--------------------------------------------
#变量初始化C
CC := g++
CPPFLAGS := -Wall -g
BIN := main
OBJS := main.o add.o sub.o
#makefile格式:分析目标和依赖关系
$(BIN):$(OBJS)
$(CC) $(CPPFLAGS) $^ -o $@
#模式规则
%:%cpp 
$(CC) $(CPPFLAGS) -c  $< -o $@
#伪目标
.PHONY:clean all
 clean:
#  rm -f *.o $(BIN)
$(RM) $(OBJS) .*.sw? *.o
echo $(SRC)
---------------------------------------------
#万能一次编译多个文件可执行文件
SRC := ${wildcard *.c}
OBJS := ${pathsubst %.c , % , $(SRC)}
CC := g++
CPPFLAGS := -Wall -g
all:$(OBJS)
%:%c
$(CC) -O $@ $^ $(CPPFLAGS)
.PHONY:clean all
clean:
    $(RM) $(OBJS) .*.sw ? *.o
    echo $(SRC)
-----------------------------------------------
#万能一次编译多个文件合成一个可执行文件
#变量初始化C
CC := g++
CPPFLAGS := -Wall -g
#BIN := main
#OBJS := main.o add.o sub.o
C_SRC = $(wildcard *.c)  
C_OBJ = $(patsubst %c, %o, $(C_SRC))  
CPP_SRC = $(wildcard *.cpp)  
CPP_OBJ = $(patsubst %cpp, %o, $(CPP_SRC))  
TARGET = main
#makefile格式:分析目标和依赖关系
.PHONY:clean all
all: $(TARGET)
$(TARGET):$(CPP_OBJ)
$(CC) $(CPPFLAGS) $^ -o $@
#$(BIN):$(OBJS)
# $(CC) $(CPPFLAGS) $^ -o $@
#模式规则
%:%cpp 
$(CC) $(CPPFLAGS) -c  $< -o $@
#伪目标

clean:
#  rm -f *.o $(BIN)
$(RM) $(CPP_OBJ) .*.sw? *.o
技术分享


总体来说:(Make将只编译改动的代码文件,而不完全编译),
1:变量初始化
2:分析目标和依赖关系{2.1:依赖不在,再次进入2;2.2:依赖在{2.2.1:目标存在:依赖不执行,目标执行;2.2.2:目标不存在:直接执行;}}
------------------------------------------------------------
1:makefile格式
目标:依赖(有几个,也可以没有)
<Tab>命令
如:
$(BIN):$(OBJS)
 $(CC) $(CPPFLAGS) $^ -o $@
%.o:%cpp
 $(CC) $(CPPFLAGS) -c  $< -o $@
.PHONY:clean
 clean:
  rm -f *.0 $(BIN)
2:make如何读取makefile规则
     读取第一条规则,分析目标和依赖关系;
      如果依赖不存在,把依赖作为新目标查找所在规则,分析目标和依赖关系;
      如果依赖存在,目标存在,依赖更新(执行命令)目标更新(不执行)
      如果依赖存在,目标不存在,直接执行命令;
3:变量
    变量种类
a,用户自定义变量;
1:简单方式 VAR:=var (推荐使用这种,先定义后使用)
2:递归展开方式VAR=var (可以向后引用变量,但是不能对变量进行任何扩展 如:CFLAGS = $(CFLAGS) - o 会造成死循环)
3:条件方式 VAR?=var (前面没有定义则这句话执行)
ps:变量使用$(VAR)
        #表示注释
        echo $(VAR)表示打印显示变量

b,预定义变量
技术分享
ps:RM 其实=rm -f命令;
c,自动变量
技术分享
d,环境变量 
make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量
 如果用户在makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量 
SHELL  :环境变量,表示当前所用的shell
CURDIR :环境变量,表示当前目录
MAKEFLAGS :环境变量,存储make的参数信息

4:makefile的规则
makefile的规则是make进行处理的依据,它包括了目标体、依赖文件及其之间的命令语句。
a,普通规则
b,隐含规则
隐含规则能够告诉make怎样使用传统的规则完成任务,这样,当用户使用它们时就不必详细指定编译的具体细节,而只需把目标文件列出即可
如:
技术分享
c,模式规则
模式规则是用来定义相同处理规则的多个文件的。它不同于隐式规则,隐式规则仅仅能够用make默认的变量来进行操作,而模式规则还能引入用户自定义变量,为多个文件建立相同的规则,从而简化了makefile的编写
模式规则的格式类似于普通规则,这个规则中的相关文件前必须用“%”标明
如:%.o : %cpp
        david : $(OBJS)
        $(CC) $^ -o $@
        %.o : %.c
       $(CC) $(CFLAGS) -c $< -o $@

总结:
模式规则:%.o  : %.c
      或者:%  : %.c
隐含规则:目标为.o文件时,该规则的命令可以省略;
5:make选项
技术分享
如:make -C ./test2 (另一个目录的makefile文件)
技术分享

总结万能例子:

编译多个c文件一般有两个功能,

第一个是每个c文件都有main函数,就是说每个c文件的可执行文件是独立的,各自是各自的;

第二个是多个c文件用来编译成一个可执行文件。

首先说第一个,内容如下,这个makefile是为了编译opencv代码的。

思路:
一般我们可以使用$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。复杂一些用法;可以使用“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o

  1. CFLAGS= -g -O3 `pkg-config opencv --cflags`  
  2. LIBS = `pkg-config opencv --libs`  
  3. C_SRC = $(wildcard *.c)  
  4. C_OBJ = $(patsubst %c, %o, $(C_SRC))  
  5. CPP_SRC = $(wildcard *.cpp)  
  6. CPP_OBJ = $(patsubst %cpp, %o, $(CPP_SRC))  
  7.   
  8. .PHONY:all clean  
  9.   
  10. all:$(CPP_OBJ) $(C_OBJ)  
  11.   
  12. .c.o:  
  13.     gcc $(CFLAGS) -o $@ $< $(LIBS)   
  14. .cpp.o:  
  15.     g++ $(CFLAGS) -o $@ $< $(LIBS)  
  16.   
  17.   
  18. clean:  
  19.     rm *~ *.o -f  


cflags 和 libs就不说了,
c_src和c_obj中,$(wildcard *.c, *.cpp, /***/***/*.c)是为了找出目录和指定目录下所有的后缀为c和cpp的文件,这个功能也可以使用c_src=$(shell echo *.c)实现。
$(patsubst %cpp, %o, $(CPP_SRC))中是为了将所有的cpp文件的后缀替换为o文件,这个功能也可以通过CPP_OBJ=$(CPP_SRC:%.c=%.o)实现
PHONY是伪目标
all后是要生成的所有目标文件
最后的.c.o和.cpp.o这两个,是为了通配编译c后缀和cpp后缀文件的规则。
这样即可编译目录下所有的源文件,为各自生成可执行文件了。
Makefile编译目录下多个文件

参考网址:http://forkhope.diandian.com/post/2012-10-12/40040828841
                    http://blog.csdn.net/jernymy/article/details/6401065
                    http://hi.baidu.com/zengzhaonong/item/f07c81e1da455210585dd89a


第二个是编译所有c文件,生成一个目标文件。有了上一个的基础,第二个目标的例子为
  1. 01 CC = gcc  
  2. 02 LD = gcc  
  3. 03 CFLAGS = -Wall -c -Dgliethttp -I../include -L lib_path  
  4. 04 LDFLAGS = -lpthread  
  5. 05   
  6. 06 SRCS = $(wildcard *.c source/*.c)  
  7. 07 OBJS = $(patsubst %c, %o, $(SRCS))  
  8. 08 TARGET = gliethttp  
  9. 09   
  10. 10 .PHONY: all clean  
  11. 11   
  12. 12 all: $(TARGET)  
  13. 13   
  14. 14 $(TARGET): $(OBJS)  
  15. 15     $(LD) $(LDFLAGS) -o $@ $^  
  16. 16   
  17. 17 %o: %c  
  18. 18     $(CC) $(CFLAGS) -o $@ $<  
  19. 19   
  20. 20 clean:  
  21. 21     rm -f *.o $(TARGET)  

Makfile相关函数说明:

1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符

例子:
建立一个测试目录,在测试目录下建立一个名为sub的子目录
$ mkdir test
$ cd test
$ mkdir sub

在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件

建立一个简单的Makefile
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )

all:
 @echo $(src)
 @echo $(dir)
 @echo $(obj)
 @echo "end"
 
执行结果分析:
第一行输出:
a.c b.c ./sub/sa.c ./sub/sb.c

wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。

第二行输出:
a.c b.c sa.c sb.c
notdir把展开的文件去除掉路径信息

第三行输出:
a.o b.o sa.o sb.o

在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用
obj=$(dir:%.c=%.o)
效果也是一样的。

这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
它的标准格式是
$(var:a=b) 或 ${var:a=b}
它的含义是把变量var中的每一个值结尾用b替换掉a

 

使用autotools:
对于一个较大的项目而言编写makefile难度较大
autotools系列工具只需用户输入简单的目标文件、依赖文件、文件目录等就可以轻松地生成makefile
autotools工具还可以完成系统配置信息的收集,从而可以方便地处理各种移植性的问题
Linux上的软件开发一般都用autotools来制作makefile
技术分享

vim编译器用法:
技术分享
编辑
新增 (append)-- a 从 光 标 所 在 位 置 後 面 开 始 新 增 资 料, 光 标 後 的 资 料 随 新 增 资 料 向 後 移 动。- A 从 光 标 所 在 列 最 後 面 的 地 方 开 始 新 增 资 料。 
插 入 (insert) -- i 从 光 标 所 在 位 置 前 面 开 始 插 入 资 料, 光 标 後 的 资 料 随 新 增 资 料 向 後 移 动。-- I 从 光 标列 的 第 一 个 非 空 白 字 符 前 面 开 始 插 入 资 料。 
开 始 (open)-- o 在 光 标 所 在 列 下 新 增 一 列 并 进 入 输 入 模 式。-- O 在 光 标 所 在 列 上 方 新 增 一 列 并 进 入 输 入 模 式。 
修改和删除
x 删除光标所在字符。
dd 删除光标所在的列。
r 修改光标所在字符,r後接著要修正的字符
R进入取代状态,新增资料会覆改原先资料, 直到按[ESC]回到指令模式下为止。
s 删除光标所在字符,并进入输入模式。
S 删除光标所在的列,并进入输入模式。
退出
<:q>不保存退出
<:q!>不保存强制性退出
<:w>保存编辑
<:w filename>存入文件filename 中
<:w! filename>强制性存入文件filename 中
<:wq>(<:x>)保存并退出(shift+zz)
光标移动
<b>移动到当前单词的开始
<e>移动到当前单词的结尾
<w>向前移动一个单词
<h>向前移动一个字符
<j>向上移动一行
<k>向下移动一行
<l>向后移动一个字符
替换操作
<r>替换光标所在的字符
<R>替换字符序列
<cw>替换一个单词
<ce>同<cw>
<cb>替换光标所在的前一字符
<c$>替换自光标位置至行尾的所有字符
<C>同<c$>
<cc>替换当前行
复制与粘贴
</yw>将光标所在单词拷入剪贴板
<y$>将光标至行尾的字符拷入剪贴板
<Y>同<y$>
<yy>将当前行拷入剪贴板
<p>将剪贴板中的内容粘贴在光标后
<P>将剪贴板中的内容粘贴在光标前

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。