• makefile学习


    Makefile基础

    一.Makefile基础

    1.1 步骤:编译-链接

    编译(compile):把源文件编译成中间目标文件(object file/.o .obj文件)

    链接(link):将中间目标文件合成执行文件

    库文件(library file):中间目标文件太多,将中间目标文件打包。(.lib 或 .a 文件)

    1.2 makefile的规则

    Target ... : prerequisites ...

    Command

    ...

    ...

    Target: 可以是object file,也可以是一个执行文件,还可以是一个标签(label)

    Prerequisites: 生成该target所依赖的文件或target

    Command:该target要执行的命令(任意的shell命令)

    这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说:

    prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。

    这就是makefile的规则,也就是makefile中最核心的内容。

     

    1.3 一个简单的例子

    edit : main.o kbd.o command.o display.o

    insert.o search.o files.o utils.o

    cc -o edit main.o kbd.o command.o display.o

    insert.o search.o files.o utils.o

    main.o : main.c defs.h

    cc -c main.c

    kbd.o : kbd.c defs.h command.h

    cc -c kbd.c

    command.o : command.c defs.h command.h

    cc -c command.c

    display.o : display.c defs.h buffer.h

    cc -c display.c

    insert.o : insert.c defs.h buffer.h

    cc -c insert.c

    search.o : search.c defs.h buffer.h

    cc -c search.c

    files.o : files.c defs.h buffer.h command.h

    cc -c files.c

    utils.o : utils.c defs.h

    cc -c utils.c

    clean :

    rm edit main.o kbd.o command.o display.o

    insert.o search.o files.o utils.o

    1.4 make 工作流程

    1. A.  Make会在当前目录下找名字叫makefile或Makefile的文件
    2. B.  如果找到,它会找文件中第一个目标文件(edit),并把这个文件作为最终的目标文件
    3. C.  如果edit文件不存在或是edit所依赖的.o文件的文件修改时间比edit新,那么会执行后面的command生成edit
    4. D.  如果edit所依赖的.o文件也不存在,那么make会在当前文件找目标为.o文件的依赖性,如果找到则再根据规则生成.o文件。

    比如,如果我们改变了command.h,那么kdb.o,command.o,file.o都会重新编译,并且edit会重新链接。

    1.5 make自动推导

    隐晦规则:

    只要make看到一个.o文件,它自动把.c文件加到依赖关系中,并且cc -c .c的command也会被推导出来。

    objects = main.o kbd.o command.o display.o

    insert.o search.o files.o utils.o

    edit : $(objects)

    cc -o edit $(objects)

    $(objects) : defs.h

    kbd.o command.o files.o : command.h

    display.o insert.o search.o files.o : buffer.h

    .PHONY : clean

    clean :

    rm edit $(objects)

    1.6 makefile内容

    A. 显示规则

    B. 隐晦规则

    C. 变量定义

    D. 文件指示( include foo.make *.mk $(bar) )

    E. 注释(#)

    F. 命令(必须以Tab键开始)

    1.7 make的工作方式

    A. 读入所有的Makefile

    B. 读入被include的其它Makefile

    C. 初始化文件中的变量

    D. 推导隐晦规则,并分析所有规则

    E. 为所有的目标文件创建依赖关系链

    F. 根据依赖关系链,决定哪些目标要重新生成

    G. 执行生成命令

    1.8 规则中的通配符

    ~ :~/test  = $HOME/test

    ~usr/test = usr宿主目录下的test

    * : *.c 所有后缀为c的文件,文件中有通配符的用转义字符 (如*)

    1.9 搜索路径

    VPATH = src: ../headers  (目录由冒号分割)

    make 依赖和目标文件在当前目录找不到的情况下会在VPATH目录中寻找

    2.0 伪目标

    .PHONY : clean

    表示并不生成clean这个文件,clean只是一个标签,make 无法生成它的依赖关系和决定它是否执行,只有显示的指明这个标签才能让其生效。

    2.1 多目标

    bigoutput littleoutput : text.g

    generate text.g -$(subst output,,$@) > $@

     

    上述规则等价于:

    bigoutput : text.g

    generate text.g -big > bigoutput

    littleoutput : text.g

    generate text.g -little > littleoutput

    2.2 静态模式

    静态模式可以更容易地定义多目标的规则

    <targets ...> : <target-pattern> : <prereq-patterns ...>

    <commands>

    例子:

    objects = foo.o bar.o

    all: $(objects)

    $(objects): %.o: %.c

    $(CC) -c $(CFLAGS) $< -o $@

    展开:

    foo.o : foo.c

    $(CC) -c $(CFLAGS) foo.c -o foo.o

    bar.o : bar.c

    $(CC) -c $(CFLAGS) bar.c -o bar.o

    2.3 定义命令包

    define run-yacc

    yacc $(firstword $^)

    mv y.tab.c $@

    endef

    2.4 变量

    Variable = xxx   Variable变量 = 赋值

    $(Variable)   括号是为了更安全的使用变量

    X := foo

    Y := $(X) bar

    X := later

    用:= 赋值变量 ,前面的变量不能使用后面的变量,只能使用前面已经定义好的变量

    ?=  如果变量已经定义,则什么也不做

    赋值语句后#的注释注意:

    Dir := /foo/bar   # directory

    那么$(Dir)/file  会是/foo/bar   /file,因为赋值后有四个空格

    2.5 变量替换

    $(var : a=b) 把变量var中所有以a字串结尾的a替换成b字串

    $(var:%.o=%.c)

    2.6 追加变量值

    Var += other

    Var := $(Var) other

    2.7 环境变量

    2.8 条件判断

    ifeq ifneq ifdef ifndef

    else

    endif

    ifeq (<arg1>, <arg2>)

    ifeq '<arg1>' '<arg2>'

    ifeq "<arg1>" "<arg2>"

    ifeq "<arg1>" '<arg2>'

    ifeq '<arg1>' "<arg2>"

    2.9 make的运行

    其他功能

    • all:这个伪目标是所有目标的目标,其功能一般是编译所有的目标。

    • clean:这个伪目标功能是删除所有被make创建的文件。

    • install:这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目

    标中去。

    • print:这个伪目标的功能是例出改变过的源文件。

    • tar:这个伪目标功能是把源程序打包备份。也就是一个tar文件。

    • dist:这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件。或是gz文件。

    • TAGS:这个伪目标功能是更新所有的目标,以备完整地重编译使用。

    • check和test:这两个伪目标一般用来测试makefile的流程。

    3.0 隐含规则

    常用的隐含规则

    1. 编译C程序的隐含规则。

    <n>.o 的目标的依赖目标会自动推导为<n>.c ,并且其生成命令是$(CC) -c

    $(CPPFLAGS) $(CFLAGS)

    2. 编译C++程序的隐含规则。

    <n>.o 的目标的依赖目标会自动推导为<n>.cc 或是<n>.C ,并且其生成命令是

    $(CXX) -c $(CPPFLAGS) $(CFLAGS)。(建议使用.cc作为C++源文件的后缀,而

    不是.C)

    模式规则示例

    %.o : %.c

    $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

    二.Makefile分析

    #当前模块的配置

    CURRENT_MODULE_PATH:=$(shell pwd)

    INC_FLAGS:=-I$(CURRENT_MODULE_PATH)/inc #加入模块头文件路径

    #工程的公共配置

    ROOT_PATH:=$(CURRENT_MODULE_PATH)/..

    PROJECT_COMMON_PATH:=$(ROOT_PATH)/common

    INC_FLAGS+=-I$(PROJECT_COMMON_PATH)/inc #加入工程公共头文件路径

    INC_FLAGS+=-I$(PROJECT_COMMON_PATH)/inc/test #加入工程公共头文件路径

    LIB_FLAGS:=-L$(PROJECT_COMMON_PATH)/lib #加入工程公共库文件路径

    #相关的配置

    SRV_PATH:=$(ROOT_PATH)/SRV

    SRV_INC_PATH:=$(SRV_PATH)/include

    SRV_LIB_PATH:=$(SRV_PATH)/lib

    SRV_INC_FLAGS:=-I$(SRV_INC_PATH)

                    -I$(SRV_INC_PATH)/pub-sub

                    -I$(SRV_INC_PATH)/infra

                    -I$(SRV_INC_PATH)/3rdparty

                    -I$(SRV_INC_PATH)/saturn

                    -I$(SRV_INC_PATH)/common

    INC_FLAGS+=$(SRV_INC_FLAGS) #加入SRV头文件路径

    LIB_FLAGS+=-L$(SRV_LIB_PATH)

    #需要连接的库

    SYS_LIBS:=-lpthread -lz -ldl -lrt -lcrypto -lssl -lm

    SRV_LIBS:=-lpubsub -linfra -lentry -lsaturn -ltimer -lprotobuf -lrestful_server -lserved -lre2 -lboost_system

                    -ldpdk -lcurl

    PROJECT_COMMON_LIBS:= #

    TEST_LIBS:= -lgtest_main -lmockcpp

    LINK_LIBS:= $(SRV_LIBS) $(SYS_LIBS) $(PROJECT_COMMON_LIBS)

    #测试代码路径

    CURRENT_MODULE_TEST_PATH:=$(CURRENT_MODULE_PATH)/test

    GCOVRFLAGS:= -fprofile-arcs -ftest-coverage

    #中间文件相关

    CURRENT_MODULE_BUILD_PATH:=$(CURRENT_MODULE_PATH)/build

    MODULE_SRC:=$(notdir $(wildcard $(CURRENT_MODULE_PATH)/src/*.cpp))

    MODULE_DEBUG_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/debug/,$(patsubst %.cpp,%.o,$(MODULE_SRC)))

    MODULE_RELEASE_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/release/,$(patsubst %.cpp,%.o,$(MODULE_SRC)))

    MODULE_TEST_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/test/,$(filter-out main.o,$(patsubst %.cpp,%.o,$(MODULE_SRC))))

    COMMON_SRC:=$(notdir $(wildcard $(PROJECT_COMMON_PATH)/src/*.cpp))

    COMMON_DEBUG_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/debug/,$(patsubst %.cpp,%.o,$(COMMON_SRC)))

    COMMON_RELEASE_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/release/,$(patsubst %.cpp,%.o,$(COMMON_SRC)))

    COMMON_TEST_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/test/,$(patsubst %.cpp,%.o,$(COMMON_SRC)))

    TEST_SRC:=$(notdir $(wildcard $(CURRENT_MODULE_TEST_PATH)/*.cpp))

    TEST_OBJS:=$(addprefix $(CURRENT_MODULE_BUILD_PATH)/test/,$(patsubst %.cpp,%.o,$(TEST_SRC)))

    #顶级目标

    DEBUG_TARGET:=$(CURRENT_MODULE_PATH)/build/DLocationCalc

    RELEASE_TARGET:=$(CURRENT_MODULE_PATH)/build/RLocationCalc

    TEST_TARGET:=$(CURRENT_MODULE_PATH)/build/TLocationCalc

    RELEASE_FLAGS:= -DNDEBUG

    DEBUG_FLAGS:=-g -DDEBUG

    TEST_FLAGS:=-g -DDEBUG  -DTEST

    CXXFLAGS+=-std=c++11

    .PHONY:default release debug test clean pre_build

    default:debug

    pre_build:

             mkdir -p $(CURRENT_MODULE_BUILD_PATH)/release

             rm -f $(CURRENT_MODULE_BUILD_PATH)/release/RLocationCalc

             mkdir -p $(CURRENT_MODULE_BUILD_PATH)/debug

             rm -f $(CURRENT_MODULE_BUILD_PATH)/debug/DLocationCalc

             mkdir -p $(CURRENT_MODULE_BUILD_PATH)/test

             rm -f $(CURRENT_MODULE_BUILD_PATH)/test/TLocationCalc

    #编译调试版本

    debug:pre_build $(DEBUG_TARGET)

    $(DEBUG_TARGET): $(MODULE_DEBUG_OBJS) $(COMMON_DEBUG_OBJS)

             $(CXX) $(CXXFLAGS) -o $@ $^ $(LIB_FLAGS) $(LINK_LIBS)

    #编译发布版本

    release:pre_build $(RELEASE_TARGET)

    $(RELEASE_TARGET):$(MODULE_RELEASE_OBJS) $(COMMON_RELEASE_OBJS)

             $(CXX) $(CXXFLAGS) -o $@ $^ $(LIB_FLAGS) $(LINK_LIBS)

    #编译测试用例并运行

    move_sample:

             cp $(CURRENT_MODULE_TEST_PATH)/test.csv $(CURRENT_MODULE_BUILD_PATH)/

    test:pre_build move_sample $(TEST_TARGET)

             export LD_LIBRARY_PATH=$(SRV_LIB_PATH) &&

             ./build/TLocationCalc --gtest_output=xml:./build/gtest.xml &&

             gcovr -r . &&

             lizard src -l cpp -C 8 -L 100 -a 6

    $(TEST_TARGET): $(MODULE_TEST_OBJS) $(COMMON_TEST_OBJS) $(TEST_OBJS)

             $(CXX) $(CXXFLAGS) -o $@ $^ $(LIB_FLAGS) $(TEST_LIBS) $(LINK_LIBS) $(GCOVRFLAGS)

    #清除

    clean:

             rm -rf $(CURRENT_MODULE_BUILD_PATH)

    # debug 版本

    $(CURRENT_MODULE_BUILD_PATH)/debug/%.o:$(CURRENT_MODULE_PATH)/src/%.cpp

             $(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(INC_FLAGS) -o $@ -c $^

    $(CURRENT_MODULE_BUILD_PATH)/debug/%.o:$(PROJECT_COMMON_PATH)/src/%.cpp

             $(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(INC_FLAGS) -o $@ -c $^

    #release 版本

    $(CURRENT_MODULE_BUILD_PATH)/release/%.o:$(CURRENT_MODULE_PATH)/src/%.cpp

             $(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(INC_FLAGS) -o $@ -c $^

    $(CURRENT_MODULE_BUILD_PATH)/release/%.o:$(PROJECT_COMMON_PATH)/src/%.cpp

             $(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(INC_FLAGS) -o $@ -c $^

    #test 版本

    $(CURRENT_MODULE_BUILD_PATH)/test/%.o:$(CURRENT_MODULE_PATH)/src/%.cpp

             $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(TEST_FLAGS) $(GCOVRFLAGS) -o $@ -c $^

    $(CURRENT_MODULE_BUILD_PATH)/test/%.o:$(PROJECT_COMMON_PATH)/src/%.cpp

             $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(TEST_FLAGS) $(GCOVRFLAGS) -o $@ -c $^

    $(CURRENT_MODULE_BUILD_PATH)/test/%.o:$(CURRENT_MODULE_TEST_PATH)/%.cpp

             $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(TEST_FLAGS) -o $@ -c $^

    三.常用命令

    A. 通配符自动展开

       在makefile的规则中,通配符会被自动展开,但是在变量的定义和函数引用时,通配符将失效,这种情况下如要用通配符,就要用函数wildcard,用法$(wildcard PATTERN..)

    例子:objects := $(wildcard *.c) 来获取工作目录中所有.c 文件列表

    B . 模式字符串替换patsubst函数

    例子:$(patsubst %.c, %.o, $(dir)) 把$(dir) 中的变量符合.c结尾的全部替换为.o

    C. 去掉路径notdir($src)

    D. 字符串替换subst

    $(subst FROM, TO, TEXT) 将TEXT中的FROM替换成TO

    E. 过滤函数filter

    例子:$(filter %.o, $(files)) 从files中过滤出.o 的文件

    F. 首单词函数firstword

    G. $( strip <string>) 去掉字串开头和结尾的空字符

    H. $(findstring <find>,<in>) 在in中查找find字串,找到返回find,否则返回空字串

    I. $(filter <pattern...>, <text>)以pattern模式过滤text中的单词,保留符合模式的单词,模式可以多个

    J. $(filter-out <pattern...>, <text>) 反过滤函数,返回不符合模式的单词

    K. $(sort <list>) 排序(升序),去掉相同的单词

    L. word,wordlist,firstword,words

    M. $(dir <names ...>) 取目录

    N. $(notdir <names ...>) 取文件函数

    O. $(suffix <names ...>)取后缀函数

    P. $(basename <names...>)取前缀函数

    Q. $(addsuffix <suffix>,<names...>) 添加后缀

    R. $(addprefix <prefix>,<names...>) 添加前缀

    S. $(join <list1>,<list2>)把list2中的单词对应加到list1的后面

    T. $(foreach <var>,<list>,<test>)将list中单词逐个取出放到var变量中,然后在执行test所包含的表达式

    U. $(if <condition>,<then-part>,<else-part>)

    四. 自动变量

    $@: 目标集合

    $<: 所有的依赖目标集第一个目标,如果依赖是模式定义的,取出一系列

    $^: 所有的依赖目标的集合,以空格分割

    $+ : 类似$^,去除重复的依赖

    $? : 所有比目标更新的依赖集合

    objects = foo.o bar.o

    all: $(objects)

    $(objects): %.o: %.c

    $(CC) -c $(CFLAGS) $< -o $@

    展开:

    foo.o : foo.c

    $(CC) -c $(CFLAGS) foo.c -o foo.o

    bar.o : bar.c

    $(CC) -c $(CFLAGS) bar.c -o bar.o

    五. 编译器g++

    gcc and g++分别是gnu的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步

    1.预处理,生成.i的文件[预处理器cpp]

    2.将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs]

    3.由汇编变为目标代码(机器代码)生成.o的文件[汇编器as]

    4.连接目标代码,生成可执行程序[链接器ld]

    常用参数:

    -ansi 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色,

    例如 asm 或 typeof 关键词。

    -c 只编译并生成目标文件。

    -DMACRO=DEFN 以字符串“DEFN”定义 MACRO 宏。

    -g 生成调试信息。GNU 调试器可利用该信息。

    -IDIRECTORY 指定额外的头文件搜索路径DIRECTORY。

    -LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。

    -lLIBRARY 连接时搜索指定的函数库LIBRARY。

    -o  FILE 生成指定的输出文件。用在生成可执行文件时。

    [参数详解]

    -x

    language filename

     设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根据约定C语言的后缀名称是.c的,而C++的后缀名是.C或者.cpp,如果你很个性,决定你的C代码文件的后缀名是.pig 哈哈,那你就要用这个参数,这个参数对他后面的文件名都起作用,除非到了下一个参数的使用。

      可以使用的参数吗有下面的这些

      `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `assembler-with-cpp'.

      看到英文,应该可以理解的。

      例子用法:

      gcc -x c hello.pig

      

    -x none filename

      关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型

      例子用法:

      gcc -x c hello.pig -x none hello2.c

      

    -c

      只激活预处理,编译,和汇编,也就是他只把程序做成obj文件

      例子用法:

      gcc -c hello.c

      他将生成.o的obj文件

    -S

      只激活预处理和编译,就是指把文件编译成为汇编代码。

      例子用法

      gcc -S hello.c

      他将生成.s的汇编代码,你可以用文本编辑器察看

    -E

      只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面.

      例子用法:

      gcc -E hello.c > pianoapan.txt

      gcc -E hello.c | more

      慢慢看吧,一个hello word 也要与处理成800行的代码

    -o

      制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果你和我有同感,改掉它,哈哈

      例子用法

      gcc -o hello.exe hello.c (哦,windows用习惯了)

      gcc -o hello.asm -S hello.c

    -pipe

      使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问题

      gcc -pipe -o hello.exe hello.c

    -ansi

      关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一些asm inline typeof关键字,以及UNIX,vax等预处理宏,

    -fno-asm

      此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作关键字。     

    -fno-strict-prototype

      只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式的对参数的个数和类型说明,而不是没有参数.

      而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说明的类型

      

    -fthis-is-varialble

      就是向传统c++看齐,可以使用this当一般变量使用.

      

    -fcond-mismatch

      允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型

      

    -funsigned-char

    -fno-signed-char

    -fsigned-char

    -fno-unsigned-char

      这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前两个参数)或者 signed char(后两个参数)

      

    -include file

      包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设定,功能就相当于在代码中使用#include<filename>

      例子用法:

      gcc hello.c -include /root/pianopan.h

      

    -i macros file

      将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件中

      

    -D macro

      相当于C语言中的#define macro

      

    -D macro=defn

      相当于C语言中的#define macro=defn

      

    -U macro

      相当于C语言中的#undef macro

    -undef

      取消对任何非标准宏的定义

      

    -Idir

      在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头文件,如果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他

      回先在你所制定的目录查找,然后再按常规的顺序去找.

      对于#include<file>,gcc/g++会到-I制定的目录查找,查找不到,然后将到系统的缺省的头文件目录查找

      

    -I-

      就是取消前一个参数的功能,所以一般在-Idir之后使用

      

    -idirafter dir

      在-I的目录里面查找失败,讲到这个目录里面查找.

      

    -iprefix prefix

    -iwithprefix dir

      一般一起使用,当-I的目录查找失败,会到prefix+dir下查找

      

    -nostdinc

      使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头文件的位置

      

    -nostdin C++

      规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创libg++库使用

      

    -C

      在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很方便的

      

    -M

      生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用gcc -M hello.c来测试一下,很简单。

      

    -MM

      和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。

      

    -MD

      和-M相同,但是输出将导入到.d的文件里面

      

    -MMD

      和-MM相同,但是输出将导入到.d的文件里面

      

    -Wa,option

      此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选项,然后传递给会汇编程序

      

    -Wl.option

      此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选项,然后传递给会连接程序.

      

    -llibrary

      制定编译的时候使用的库

      例子用法

      gcc -lcurses hello.c

      使用ncurses库编译程序

      

    -Ldir

      制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然

      编译器将只在标准库的目录找。这个dir就是目录的名称。

      

    -O0

    -O1

    -O2

    -O3

      编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高     

    -g

      只是编译器,在编译的时候,产生调试信息。

      

    -gstabs

      此选项以stabs格式声称调试信息,但是不包括gdb调试信息.

      

    -gstabs+

      此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.

      

    -ggdb

      此选项将尽可能的生成gdb的可以使用的调试信息.

    -static

      此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么

    动态连接库,就可以运行.

    -share

      此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.

    -traditional

      试图让编译器支持传统的C语言特性

    六.make命令参数

    下面列举了所有GNU make 3.80版的参数定义。其它版本和产商的make大同小异,不过其它产商的make的具体参数还是请参考各自的产品文档。

    “-b”
    “-m”
    这两个参数的作用是忽略和其它版本make的兼容性。

    “-B”
    “--always-make”
    认为所有的目标都需要更新(重编译)。

    “-C <dir>”
    “--directory=<dir>”
    指定读取makefile的目录。如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:“make –C ~hchen/test –C prog”等价于“make –C ~hchen/test/prog”

    “—debug[=<options>]”
    输出make的调试信息。它有几种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。下面是<options>的取值:
        a —— 也就是all,输出所有的调试信息。(会非常的多)
        b —— 也就是basic,只输出简单的调试信息。即输出不需要重编译的目标。
        v —— 也就是verbose,在b选项的级别之上。输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或是依赖目标)等。
        i —— 也就是implicit,输出所以的隐含规则。
        j —— 也就是jobs,输出执行规则中命令的详细信息,如命令的PID、返回码等。
        m —— 也就是makefile,输出make读取makefile,更新makefile,执行makefile的信息。

    “-d”
    相当于“--debug=a”

    “-e”
    “--environment-overrides”
    指明环境变量的值覆盖makefile中定义的变量的值。

    “-f=<file>”
    “--file=<file>”
    “--makefile=<file>”
    指定需要执行的makefile

    “-h”
    “--help”
    显示帮助信息。

    “-i”
    “--ignore-errors”
    在执行时忽略所有的错误。

    “-I <dir>”
    “--include-dir=<dir>”
    指定一个被包含makefile的搜索目标。可以使用多个“-I”参数来指定多个目录。

    “-j [<jobsnum>]”
    “--jobs[=<jobsnum>]”
    指同时运行命令的个数。如果-j后没有这个jobsnum参数,make运行命令时能运行多少就运行多少。如果有一个以上的“-j”参数,那么仅最后一个“-j”才是有效的。(注意这个参数在MS-DOS中是无用的)

    “-k”
    “--keep-going”
    出错也不停止运行。如果生成一个目标失败了,那么依赖于其上的目标就不会被执行了。

    “-l <load>”
    “--load-average[=<load]”
    “—max-load[=<load>]”
    指定make运行命令的负载。

    “-n”
    “--just-print”
    “--dry-run”
    “--recon”
    仅输出执行过程中的命令序列,但并不执行。

    “-o <file>”
    “--old-file=<file>”
    “--assume-old=<file>”
    不重新生成的指定的<file>,即使这个目标的依赖文件新于它。

    “-p”
    “--print-data-base”
    输出makefile中的所有数据,包括所有的规则和变量。这个参数会让一个简单的makefile都会输出一堆信息。如果你只是想输出信息而不想执行 makefile,你可以使用“make -qp”命令。如果你想查看执行makefile前的预设变量和规则,你可以使用“make –p –f /dev/null”。这个参数输出的信息会包含着你的makefile文件的文件名和行号,所以,用这个参数来调试你的makefile会是很有用的, 特别是当你的环境变量很复杂的时候。

    “-q”
    “--question”
    不运行命令,也不输出。仅仅是检查所指定的目标是否需要更新。如果是0则说明要更新,如果是2则说明有错误发生。

    “-r”
    “--no-builtin-rules”
    禁止make使用任何隐含规则。

    “-R”
    “--no-builtin-variabes”
    禁止make使用任何作用于变量上的隐含规则。

    “-s”
    “--silent”
    “--quiet”
    在命令运行时不输出命令的输出。

    “-S”
    “--no-keep-going”
    “--stop”
    取消“-k”选项的作用。因为有些时候,make的选项是从环境变量“MAKEFLAGS”中继承下来的。所以你可以在命令行中使用这个参数来让环境变量中的“-k”选项失效。

    “-t”
    “--touch”
    相当于UNIXtouch命令,只是把目标的修改日期变成最新的,也就是阻止生成目标的命令运行。

    “-v”
    “--version”
    输出make程序的版本、版权等关于make的信息。

    “-w”
    “--print-directory”
    输出运行makefile之前和之后的信息。这个参数对于跟踪嵌套式调用make时很有用。

    “--no-print-directory”
    禁止“-w”选项。

    “-W <file>”
    “--what-if=<file>”
    “--new-file=<file>”
    “--assume-file=<file>”
    假定目标<file>需要更新,如果和“-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有“-n”那么就像运行UNIX“touch”命令一样,使得<file>的修改时间为当前时间。

    “--warn-undefined-variables”
    只要make发现有未定义的变量,那么就输出警告信息

  • 相关阅读:
    contest hunter5105 Cookies
    bzoj2599: [IOI2011]Race
    poj1741 Tree
    bzoj2527: [Poi2011]Meteors
    bzoj3673: 可持久化并查集 by zky&&3674: 可持久化并查集加强版
    bzoj2741: 【FOTILE模拟赛】L
    bzoj3110: [Zjoi2013]K大数查询
    bzoj1901: Zju2112 Dynamic Rankings
    bzoj2821: 作诗(Poetize)
    poj1417 True Liars
  • 原文地址:https://www.cnblogs.com/sunnypoem/p/9551352.html
Copyright © 2020-2023  润新知