当前位置:文档之家› 2.Android源代码编译命令m和mm和mmm以及make分析

2.Android源代码编译命令m和mm和mmm以及make分析

2.Android源代码编译命令m和mm和mmm以及make分析
2.Android源代码编译命令m和mm和mmm以及make分析

老罗的新浪微博:https://www.doczj.com/doc/e22944376.html,/shengyangluo,欢迎关注!

在前文中,我们分析了Android编译环境的初始化过程。Android编译环境初始化完成后,我们就可以用m/mm/mmm/make命令编译源代码了。当然,这要求每一个模块都有一个Android.mk文件。Android.mk实际上是一个Makefile脚本,用来描述模块编译信息。Android编译系统通过整合Android.mk文件完成编译过程。本文就对Android源代码的编译过程进行详细分析。

从前面Android编译系统环境初始化过程分析这篇文章可以知道,lunch命令其实是定义在build/envsetup.sh文件中的函数lunch提供的。与lunch命令一样,m、mm和mmm 命令也分别是由定义在build/envsetup.sh文件中的函数m、mm和mmm提供的,而这三个函数又都是通过make命令来对源代码进行编译的。事实上,命令m就是对make命令的简单封装,并且是用来对整个Android源代码进行编译,而命令mm和mmm都是通过make命令来对Android源码中的指定模块进行编译。接下来我们就先分别介绍一下函数m、mm和mmm的实现,然后进一步分析它们是如何通过make命令来编译代码的。

函数m的实现如下所示:

函数m调用函数gettop得到的是Android源代码根目录T。在执行make命令的时候,先通过-C选项指定工作目录为T,即Android源代码根目录,接着又将执行命令m指定的参数$@作为命令make的参数。从这里就可以看出,命令m实际上就是对命令make的简单封装。

函数mm的实现如下所示:

函数mm首先是判断当前目录是否就是Android源码根目录,即当前目录下是否存在一个build/core/envsetup.mk文件和一个Makefile文件。如果是的话,就将命令mm当作是一个普通的make命令来执行。否则的话,就调用函数findmakefile从当前目录开始一直往上寻找是否存在一个Android.mk文件。如果在寻找的过程中,发现了一个Android.mk 文件,那么就获得它的绝对路径,并且停止上述寻找过程。

由于接下来执行make命令时,我们需要指定的是要编译的Android.mk文件的相对于Android源码根目录路径,因此函数mm需要将刚才找到的Android.mk绝对文件路径M 中与Android源码根目录T相同的那部分路径去掉。这是通过sed命令来实现的,也就是将字符串M前面与字符串T相同的子串删掉。

最后,将找到的Android.mk文件的相对路径设置给环境变量ONE_SHOT_MAKE,表示接下来要对它进行编译。另外,函数mm还将make命令目标设置为all_modules。这是什么意思呢?我们知道,一个Android.mk文件同时可以定义多个模块,因此,all_modules 就表示要对前面指定的Android.mk文件中定义的所有模块进行编译。

函数mmm的实现如下所示:

[plain]view plaincopy

函数mmm的实现就稍微复杂一点,我们详细解释一下。

首先,命令mmm可以这样执行:

其中,dir-1、dir-2、dir-N都是包含有Android.mk文件的目录。在最后一个目录dir-N 的后面可以带一个冒号,冒号后面可以通过逗号分隔一系列的模块名称module-1、module-2和module-M,用来表示要编译前面指定的Android.mk中的哪些模块。

知道了命令mmm的使用方法之后,我们就可以分析函数mmm的执行逻辑了:

1. 调用函数gettop获得Android源码根目录。

2. 通过命令awk将执行命令mmm时指定的选项参数提取出来,也就是将以横线“-”开头的字符串提取出来,并且保存在变量DASH_ARGS中。

3. 通过命令awk将执行命令mmm时指定的非选项参数提取出来,也就是将非以横线“-”开头的字符串提取出来,并且保存在变量DIRS中。这里得到的实际上就是跟在命令mmm后面的字符串“ ... [:module-1,module-2,...,module-M]”。

4. 变量DIRS保存的字符串可以看成是一系以空格分隔的子字符串,因此,就可以通过一个for循环来对这些子字府串进行遍历。每一个子字符串DIR描述的都是一个包含有Android.mk文件的目录。对每一个目录DIR执行以下操作:

4.1 由于目录DIR后面可能会通过冒号指定有模块名称,因此就先通过两个sed命令来获得这些模块名称。第一个sed命令获得的是一系列以逗号分隔的模块名称列表,第二个sed命令用来将前面获得的以逗号分隔的模块名称列表转化为以空格分隔的模块名称列表。最后,获得的以空格分隔的模块名称列表保存在变量MODULES中。由于目录DIR后面也可能不指定有模块名称,因此前面得到的变量MODULES的值就会为空。在这种情况下,需要将变量MODULES的值设置为“all_modules”,表示要编译的是所有模块。

4.2 通过两个sed命令获得真正的目录DIR。第一个sed命令将原来DIR字符串后面的冒号以及冒号后面的模块列表字符串删掉。第二个sed命令将执行前面一个sed命令获得的目录后面的"/"斜线去掉,最后就得到一个末尾不带有斜线“/”的路径,并且保存在变量DIR中。

4.3 如果变量DIR描述的是一个真正的路径,也就是在该路径下存在一个Android.mk 文件,那么就进行以下处理:

4.3.1 统计Android源码根目录T包含的字符数,并且将这个字符数加1,得到的值保存在变量TO_CHOP中。

4.3.2 通过执行/bin/pwd命令获得当前执行命令mmm的目录START。

4.3.3 通过cut命令获得当前目录START相对于Android源码根目录T的路径,并且保存在变量MFILE中。

4.3.4 如果变量MFILE的值等于空,就表明是在Android源码根目录T中执行mmm 命令,这时候就表明变量DIR描述的就是相对Android源码根目录T的一个目录,这时候指定的Android.mk文件相对于Android源码根目录T的路径就为$DIR/Android.mk。

4.3.5 如果变量MFILE的值不等于空,就表明是在Android源码根目录T的某一个子目录中执行mmm命令,这时候$MFILE/$DIR/Android.mk表示的Android.mk文件路径才是相对于Android源码根目录T的。

4.3.6 将获得的Android.mk路径MFILE附加在变量MAKEFILE描述的字符串的后面,并且以空格分隔。

4.4 如果变量DIR描述的不是一个真正的路径,并且它的值等于"snod"、"showcomands"、“dist”或者“incrementaljavac”,那么它描述的其实是make修饰命令。这四个修饰命令的含义分别如下所示:

4.4.1 snod是“systemimage with no dependencies”的意思,表示忽略依赖性地重新打包system.img。

4.4.2 showcommands表示显示编译过程中执行的命令。

4.4.3 dist表示将编译后产生的发布文件拷贝到out/dist目录中。

4.4.4 incrementaljavac表示对Java源文件采用增量式编译,也就是如果一个Java文件如果没有修改过,那么就不要重新生成对应的class文件。

5. 上面的for循环执行完毕,变量MAKEFILE保存的是要编译的Android.mk文件列表,它们都是相对于Android源码根目录的路径,变量DASH_ARGS保存的是原来执行mmm命令时带的选项参数,变量MODULES保存的是指定要编译的模块名称,变量ARGS 保存的是修饰命令。其中,变量MAKEFILE的内容通过环境变量ONE_SHOT_MAKEFILE 传递给make命令,而其余变量都是通过参数的形式传递给make命令,并且变量MODULES 作为make命令的目标。

明白了函数m、mm和mmm的实现之后,我们就可以知道:

1. mm和mmm命令是类似的,它们都是用来编译某些模块。

2. m命令用来编译所有模块。

如果我们理解了mm或者mmm命令的编译过程,那么自然也会明白m命令的编译过程,因为所有模块的编译过程就等于把每一个模块的编译都编译出来,因此,接下来我们就选择具有代表性的、常用的编译命令mmm来分析Android源码的编译过程,如图1所示:

图1 mmm命令的编译过程

函数mmm在Android源码根目录执行make命令的时候,没有通过-f指定Makefile 文件,因此默认就使用Android源码根目录下的Makefile文件,它的内容如下所示:

它仅仅是将build/core/main.mk文件加载进来。build/core/main.mk是Android编译系统的入口文件,它通过加载其它的mk文件来对Android源码中的各个模块进行编译,以及将编译出来的文件打包成各种镜像文件。以下就是build/core/main.mk文件的主要内容:

接下来我们就先对build/core/main.mk文件的核心逻辑进行分析,然后再进一步对其中涉及到的关键点进行分析。

build/core/main.mk文件的执行过程如下所示:

1. 定义默认make目标为droid。目标droid根据不同的情形有不同的依赖关系。如果在初始化编译环境时,指定了TARGET_BUILD_APPS环境变量,那么就表示当前只编译特定的模块,这些特定的模块保存在变量unbundled_build_modules中,这时候目标droid 就透过另外一个伪目标app_only依赖它们。如果在初始化编译环境时没有指定

TARGET_BUILD_APPS环境变量,那么目标droid就依赖于另外两个文件droidcore和

dist_files。droidcore是一个make伪目标,它依赖于各种预编译文件,以及system.img、boot.img、recovery.img和userdata.img等镜像文件。dist_files也是一个make伪目标,用来指定一些需要在编译后拷贝到out/dist目录的文件。也就是说,当我们在Android源码目录中执行不带目标的make命令时,默认就会对目标droid进行编译,也就是会将整个Android系统编译出来。

2. 加载build/core/config.mk文件。从前面Android编译系统环境初始化过程分析一文可以知道,在加载build/core/config.mk文件的过程中,会在执行make命令的进程中完成对Android编译环境的初始化过程,也就是会指定好目标设备以及编译类型。

3. 加载build/croe/definitions.mk文件。该文件定义了很多在编译过程中要用到的宏,相当于就是定义了很多通用函数,供编译过程调用。

4. 如果在执行make命令时,指定的不是清理文件相关的目标,也就是不是clean、clobber、dataclean和installclean等目标,那么就会将变量dont_bother的值设置为true,表示接下来要执行的是编译命令。

5. 在变量dont_bother的值等于true的情况下,如果环境变量ONE_SHOT_MAKEFILE的值不等于空,也就是我们执行的是mm 或者mmm命令,那么就表示要编译的是特定的模块。这些指定要编译的模块的Android.mk文件路径就保存在环境变量

ONE_SHOT_MAKEFILE中,因此直接将这些Android,mk文件加载进来就获得相应的编译规则。另一方面,如果环境变量

ONE_SHOT_MAKEFILE的值等于空,那么就说明我们执行的是m 或者make命令,那么就表示要对Android源代码中的所有模块进行编译,这时候就通过build/tools/findleaves.py脚本获得Android 源代码工程下的所有Android.mk文件的路径列表,并且将这些Android.mk文件加载进行获得相应的编译规则。

6. 上一步指定的Android.mk文件加载完成之后,变量ALL_MODULES就包含了所有要编译的模块的名称,这些模块名称以空格来分隔形成一个列表。

7. 生成模块依赖规则。每一个模块都可以通过LOCAL_REQUIRED_MODULES来指定它所依赖的其它模块,也就是说当一个模块被安装时,它所依赖的其它模块也同样会被安装。每一个模块m依赖的所有模块都会被保存在ALL_MODULES.$(m).REQUIRED变量中。对于每一个被依赖模块r,我们需要获得它的安装文件,也就是最终生成的模块文件的文件路径,以便可以生成相应的编译规则。获得一个模块m的安装文件是通过调用函数module-installed-files来实现的,实质上就是保存在$(ALL_MODULES.$(m).INSTALLED 变量中。知道了一个模块m的所依赖的模块的安装文件路径之后,我们就可以通过函数add-required-deps来指定它们之间的依赖关系了。注意,这里实际上指定的是模块m的安装文件与它所依赖的模块r的安装文件的依赖关系。

8.将所有要安装的模块都保存在变量

ALL_DEFAULT_INSTALLED_MODULES中,并且将

build/core/Makefie文件加载进来。build/core/Makefie文件会根据要安装的模块产成system.img、boot.img和recovery.img等镜像文件的生成规则。

9. 前面提到,当执行mm命令时,make目标指定为all_moudles。另外,当执行mmm 命令时,默认的make目标也指定为all_moudles。因此,我们需要指定目标all_modules 的编译规则,实际上只要将它依赖于当前要编译的所有模块就行了,也就是依赖于由变量ALL_MODULES所描述的模块。

在上述过程中,最核心的就是第5步和第8步。由于本文只关心Android源码的编译过程,因此我们只分析第5步的执行过程。在接下来一篇文章中分析Android镜像文件的生成过程时,我们再分析第8步的执行过程。

第5步实际上就是将指定模块的Android.mk文件加载进来。一个典型的Android.mk 文件如下所示:

以LOCAL开头的变量都是属于模块局部变量,也就是说,一个模块在开始编译之前,必须要先对它们进行清理,然后再进行初始化。Android编译系统定义了非常多的模块局部变量,因此我们不可能手动地一个一个清理,需要加载一个由变量CLEAR_VARS指定的Makefile脚本来帮我们自动清理。变量CLEAR_VARS的值定义在build/core/config.mk文件,它的值等于build/core/clear_vars.mk。

Android.mk文件中还有一个重要的变量LOCAL_PATH,用来指定当前正在编译的模块的目录,我们可以通过调用宏my-dir来获得。宏my-dir定义在build/core/definitions.mk 文件,它实际上就是将当前正在加载的Android.mk文件路径的目录名提取出来。

Android.mk文件接下来就是通过其它的LOCAL变量定义模块名称、源文件,以及所要依赖的各种库文件等等。例如,在我们这个例子,模块名称定义为libdis,参与编译的源文件为dispatcher.cpp和common.cpp、依赖的库文件为liblog和libdl。

最后,Android文件通过加载一个模板文件来告诉编译系统它所要编译的模块的类型。例如,在我们这个例子中,就是通过加载由变量BUILD_SHARED_LIBRARY指定的模板文件来告诉编译系统我们要编译的模块是一个动态链接库。变量BUILD_SHARED_LIBRARY 的值定义在build/core/config.mk文件,它的值等于build/core/shared_library.mk。

Android编译系统定义了非常多的模板文件,每一个模板文件都对应一种类型的模块,例如除了我们上面的动态链接库模板文件之外,还有:

BUILD_PACKAGE:指向build/core/package.mk,用来编译APK文件。

BUILD_JAVA_LIBRARY:指向build/core/java_library.mk,用来编译Java库文件。

BUILD_STATIC_JAVA_LIBRARY:指向build/core/tatic_java_library.mk,用来编译Java静态库文件。

BUILD_STATIC_LIBRARY:指向build/core/static_library.mk,用来编译静态库文件。也就是.a文件。

BUILD_EXECUTABLE:指向build/core/executable.mk,用来编译可执行文件。

BUILD_PREBUILT:指向build/core/prebuilt.mk。用来编译已经预编译好的第三方库文件,实际上是将这些预编译好的第三方库文件拷贝到合适的位置去,以便可以让其它模块引用。

不管编译何种类型的模块,都是主要完成以下的工作:

1. 制定好相应的依赖规则

2. 调用合适的命令进行编译

为了简单起见,接下来我们就以动态链接库(即.so文件)的编译过程为例来说明Android编译命令mmm的执行过程。

在分析动态链接库的编译过程之前,我们首先看一看使用mmm命令来编译上述的Android.mk文件时得到的输出,如下所示:

从这些输出我们大体推断出一些文件之间的依赖关系及其生成过程:

1.

out/target/product/generic/obj/SHARED_LIBRARIES/libdis_intermediates/LINKED/libdis. so文件依赖于external/si/dispatcher/dispatcher.cpp和

external/si/dispatcher/../common/common.cpp文件,并且由它们生成。

2. out/target/product/generic/symbols/system/lib/libdis.so依赖于

out/target/product/generic/obj/SHARED_LIBRARIES/libdis_intermediates/LINKED/libdis. so文件,并且由它生成。

3. out/target/product/generic/obj/lib/libdis.so依赖于

out/target/product/generic/symbols/system/lib/libdis.so文件,并且由它生成。

4. out/target/product/generic/system/lib/libdis.so依赖于

out/target/product/generic/obj/lib/libdis.so文件,并且由它生成。

回忆前面的分析,我们提到,当执行mmm命令时,默认的make目标是all_modules,并且它依赖于变量ALL_MODULES指向的文件或者目标,因此,我们可以继续推断出,变量ALL_MODULES指向的文件或者目标一定会与文件

out/target/product/generic/system/lib/libdis.so有依赖关系,这样才能够从make目标

all_modules开始链式地生成上述文件。在接下来的分析中,我们就按照抓住上述文件的依赖关系进行逆向分析。

从上面的分析可以知道,在编译动态链接库文件的过程中,文件

build/core/shared_library.mk会被加载,它的核心内容如下所示:

LOCAL_MODULE_CLASS用来描述模块文件的类型。对于动态链接库文件来说,如果我们没有对它进行设置的话,它的默认值就等于SHARED_LIBRARIES。

LOCAL_MODULE_SUFFIX用来描述生成的模块文件的后缀名。对于动态链接库文件来说,如果我们没有对它进行设置的话,它的默认值就等于TARGET_SHLIB_SUFFIX。即.so。

上述两个变量限定了生成的动态链接库文件的完整文件名以及保存位置。

接下来,build/core/shared_library.mk文件加载了另外一个文件

build/core/dynamic_binary.mk文件,并且为变量linked_module指向的文件制定了一个依赖规则,这个依赖规则由函数transform-o-to-shared-lib来执行。从函数

transform-o-to-shared-lib就可以知道,它是根据一系列的中间编译文件(object文件)以及依赖库文件生成指定的动态链库文件的,主要就是由变量all_objects和all_libraries所描述的文件。现在,变量linked_module、all_objects和all_libraries所指向的文件是我们所要关心的。

我们接着分析文件build/core/dynamic_binary.mk文件的加载过程,它的内容如下所示:

LOCAL_UNSTRIPPED_PATH描述的是带符号的模块文件的输出目录。如果我们没有设置它,并且也没有设置变量LOCAL_MODULE_PATH的值,那么它的默认值就会与当前要编译的产品以及当前要编译的模块文件类型有关。例如,如果我们在执行lunch命令时,选择的是目标产品是模拟器,并且当前要编译的是动态链接库文件,那么得到的

LOCAL_UNSTRIPPED_PATH值就为

TARGET_OUT_$(LOCAL_MODULE_CLASS)_UNSTRIPPED。将

$(LOCAL_MODULE_CLASS)替换为SHARED_LIBRARIES,就得到

LOCAL_UNSTRIPPED_PATH的值为

TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED,它值就等于

out/target/product/generic/symbols/system/lib。也就是说,我们在为模拟器编译动态链接库模块时,生成的带符号文件都保存在目录out/target/product/generic/symbols/system/lib 中。

如果我们没有设置LOCAL_MODULE_STEM的值的话,那么它的默认值就等在我们在Android.mk文件中设置的LOCAL_MODULE的值。在我们的例子中,

LOCAL_MODULE_STEM的值就等于LOCAL_MODULE的值,即libdis。

LOCAL_INSTALLED_MODULE_STEM和LOCAL_BUILT_MODULE_STEM的值等于LOCAL_MODULE_STEM的值再加上后缀名LOCAL_MODULE_SUFFIX。在我们的例子中,LOCAL_INSTALLED_MODULE_STEM和LOCAL_BUILT_MODULE_STEM的值就等于libdis.so。

这里调用函数local-intermediates-dir得到的是动态链接文件的中间输出目录,默认就是out/target/product/generic/obj/SHARED_LIBRARIES/libdis_intermediates了,因此,我们就可以得到变量linked_module的值为

out/target/product/generic/obj/SHARED_LIBRARIES/libdis_intermediates/LINKED/libdis. so,这是编译过程要生成的文件之一。

LOCAL_INTERMEDIATE_TARGETS的值被设置为linked_module的值,接下来在加载build/core/binary.mk文件时需要用到。

接下来会根据

out/target/product/generic/obj/SHARED_LIBRARIES/libdis_intermediates/LINKED/libdis. so文件生成另外三个文件:

1. 生成带符号压缩的模块文件,前提是LOCAL_COMPRESS_MODULE_SYMBOLS 的值等于true。输入是compress_input,即linked_module,输出是compress_output,即$(intermediates)/COMPRESSED-$(LOCAL_BUILT_MODULE_STEM)。注意。目前还不支持此类型的模块文件。因此,当变量LOCAL_COMPRESS_MODULE_SYMBOLS的值等于true时,就会报错。

2. 拷贝一份带符号的模块文件到LOCAL_UNSTRIPPED_PATH描述的目录中去,即out/target/product/generic/symbols/system/lib目录。在我们这个情景中,得到的文件即为out/target/product/generic/symbols/system/lib/libdis.so。

3. 生成不带符号的模块文件,前提是LOCAL_STRIP_MODULE的值等于true。输入是前面拷贝到out/target/product/generic/symbols/system/lib目录的文件,输出由变量LOCAL_BUILT_MODULE指定。变量LOCAL_BUILT_MODULE的值是在加载文件

build/core/binary.mk的过程中指定的。

到目前为止,我们就解决前面提到的文件

out/target/product/generic/obj/SHARED_LIBRARIES/libdis_intermediates/LINKED/libdis. so和out/target/product/generic/symbols/system/lib/libdis.so的生成过程,还剩下

out/target/product/generic/obj/lib/libdis.so和out/target/product/generic/system/lib/libdis.so 文件的生成过程未搞清楚。这就需要继续分析文件build/core/binary.mk的加载过程。

文件build/core/binary.mk的核心内容如下所示:

adb基本的命令讲解教程【安卓通用】

一、【问与答】 疑问:adb是什么? 回答:adb的全称为Android Debug Bridge,就是起到调试桥的作用。通过adb我们可以在Eclipse中方面通过DDMS 来调试Android程序,说白了就是debug工具。adb的工作方式比较特殊,采用监听Socket T CP 5554等端口的方式让IDE和Qemu通讯,默认情况下adb会daemon相关的网络端口,所以当我们运行Eclipse时adb进程就会自动运行。 疑问:adb有什么用? 回答:借助adb工具,我们可以管理设备或手机模拟器的状态。还可以进行很多手机操作,如安装软件、系统升级、运行shell命令等等。其实简而言说,adb就是连接Android手机与PC端的桥梁,可以让用户在电脑上对手机进行全面的操作。 疑问:作为最关键的问题,adb工具如何用? 回答:这也是今天这篇教程的关键所在,下面我会为大家介绍一下adb工具如何操作,并介绍几个常用命令以备大家参考! 二、【准备工作】 步骤1:安装USB驱动 下载并安装H TC完整驱动程序( HTCDriver3.0.0.018.exe(13.48 MB, 下载次数: 75) ) 手机进入设置-应用程序-开发-USB调试,将第一个选项打钩选中。然后通过USB线连接电脑,提示安装驱动。 步骤2:软件准备 1、把ADB工具adb.rar(375.41 KB, 下载次数: 161) 解压放到你的电脑系统盘的根目录下 2、运行中,输入cmd进入命令提示符。以下命令均在命令提示符下进行。开始(点开始在输入框里输入CMD) 3、输入cd c:\adb回车,进入ADB所在目录

Make命令完全详解教程

Make命令完全详解教程 无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说简直就是一场灾难。而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。因此,有效的利用make和makefile工具可以大大提高项目开发的效率。同时掌握make和makefile之后,您也不会再面对着Linux下的应用软件手足无措了。

一、Make程序的命令行选项和参数 Make命令参数的典型序列如下所示: make [-f makefile文件名][选项][宏定义][目标] 这里用[]括起来的表示是可选的。命令行选项由破折号“–”指明,后面跟选项,如 也可以每个选项使用一个破折号,如 Make命令本身的命令行选项较多,这里只介绍在开发程序时最为常用的三个,它们是: –k: 如果使用该选项,即使make程序遇到错误也会继续向下运行;如果没有该选项,在遇到第一个错误时make程序马上就会停止,那么后面的错误情况就不得而知了。我们可以利用这个选项来查出所有有编译问题的源文件。 –n: 该选项使make程序进入非执行模式,也就是说将原来应该执行的命令输出,

而不是执行。 –f : 指定作为makefile的文件的名称。如果不用该选项,那么make程序首先在当前目录查找名为makefile的文件,如果没有找到,它就会转而查找名为Makefile的文件。如果您在Linux下使用GNU Make的话,它会首先查找GNUmakefile,之后再搜索makefile和Makefile。按照惯例,许多Linux程序员使用Makefile,因为这样能使Makefile出现在目录中所有以小写字母命名的文件的前面。所以,最好不要使用GNUmakefile这一名称,因为它只适用于make程序的GNU版本。 当我们想构建指定目标的时候,比如要生成某个可执行文件,那么就可以在make命令行中给出该目标的名称;如果命令行中没有给出目标的话,make命令会设法构建makefile中的第一个目标。我们可以利用这一特点,将all作为makefile中的第一个目标,然后将让目标作为all所依赖的目标,这样,当命令行中没有给出目标时,也能确保它会被构建。

cmd命令行教程

CMD 命令行高级教程 CMD命令行高级教程精选合 目录 第一章批处理基础 第一节常用批处理内部命令简介 1、REM 和:: 2、ECHO 和@ 3、PAUSE 4、ERRORLEVEL 5、TITLE 6、COLOR 7、mode 配置系统设备 8、GOTO 和: 9、FIND 10、START 11、assoc 和ftype 12、pushd 和popd 13、CALL 14、shift 15、IF 16、setlocal 与变量延迟DISABLEDELAYEDEXPANSION 启动或停用延缓环境变量扩展名。) 17、ATTRIB 显示或更改文件属性 第二节常用特殊符号 1、@ 命令行回显屏蔽符 2、% 批处理变量引导符 3、> 重定向符 4、>> 重定向符 5、<、>&、<& 重定向符 6、| 命令管道符 7、^ 转义字符 8、& 组合命令 9、&& 组合命令 10、|| 组合命令 11、"" 字符串界定符 12、, 逗号 13、; 分号 14、() 括号 15、! 感叹号 第二章FOR命令详解 一、基本格式 二、参数/d 仅为目录

三、参数/R 递归(文件名) 四、参数/L 迭代数值范围 五、参数/F 迭代及文件解析 第三章FOR命令中的变量 一、~I - 删除任何引号("),扩展%I 二、%~fI - 将%I 扩展到一个完全合格的路径名 三、%~dI - 仅将%I 扩展到一个驱动器号 四、%~pI - 仅将%I 扩展到一个路径 五、%~nI - 仅将%I 扩展到一个文件名 六、%~xI - 仅将%I 扩展到一个文件扩展名 七、%~sI - 扩展的路径只含有短名 八、%~aI - 将%I 扩展到文件的文件属性 九、%~tI - 将%I 扩展到文件的日期/时间 十、%~zI - 将%I 扩展到文件的大小 十一、%~$PATH:I 第四章批处理中的变量 一、系统变量 二、自定义变量 第五章set命令详解 一、用set命令设置自定义变量 二、用set命令进行简单计算 三、用set命令进行字符串处理 1、字符串替换 2、字符串截取 第六章if命令讲解 第一种用法:IF [NOT] ERRORLEVEL number command 第二种用法:IF [NOT] string1==string2 command 第三种用法:IF [NOT] EXIST filename command 第四种用法:IF增强的用法 第七章DOS 编程高级技巧 一、界面设计 二、if…else…条件语句 三、循环语句 四、子程序 五、用ftp 命令实现自动下载 六、用7-ZIP实现命令行压缩和解压功能 七、调用VBScript 程序 八、将批处理转化为可执行文件 九、时间延迟 1、利用ping命令延时 2、利用for命令延时 3、利用vbs延迟函数,精确度毫秒,误差1000毫秒内 4、仅用批处理命令实现任意时间延迟,精确度10 毫秒,误差50 毫秒内 十、模拟进度条

bat脚本学习教程(珍藏版)

Bat脚本基础教程 TYPE显示文本文件的内容。 [drive:][path]filename SETLOCAL开始批处理文件中环境改动的本地化操作。 在执行SETLOCAL 之后所做的环境改动只限于批处理文件。要还原原先的设置,必须执行ENDLOCAL。达到批处理文件结尾时,对于该批处理文件的每个 尚未执行的SETLOCAL 命令,都会有一个隐含的ENDLOCAL 被执行。 SETLOCAL 如果命令扩展名被启用,SETLOCAL 会如下改变: SETLOCAL 批命令现在可以接受可选参数: ENABLEEXTENSIONS / DISABLEEXTENSIONS 启动或停用命令处理器扩展名。详细信息,请参阅CMD /?。 ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION 启动或停用延缓环境变量扩展名。详细信息,请 参阅SET /? 。 无论在SETLOCAL 命令之前它们的设置是什么,这些修改会一直 保留到匹配的ENDLOCAL 命令。 如果有一个参数,SETLOCAL 命令将设置ERRORLEVEL 的值。 如果有两个有效参数中的一个,该值则为零。用下列技巧,您 可以在批脚本中使用这个来决定扩展名是否可用: VERIFY OTHER 2>nul SETLOCAL ENABLEEXTENSIONS IF ERRORLEVEL 1 echo Unable to enable extensions 这个方法之所以有效,是因为在CMD.EXE 的旧版本上,SETLOCAL 不设置ERRORLEVEL 值。具有不正确参数的VERIFY 命令将 ERRORLEVEL 值初始化成非零值。 POPD命令选项到保存在PUSHD 命令里的目录。 如果命令扩展名被启用,从推目录堆栈POPD 驱动器时,POPD 命令会删除PUSHD 创建的临时驱动器号。 PUSHD保存当前目录以供POPD 命令使用,然后改到指定的目录。 PUSHD [path | ..] path 指定要成为当前目录的目录。 如果命令扩展名被启用,除了一般驱动器号和路径,PUSHD 命令还接受网络路径。如果指定了网络路径,PUSHD 将创建一个

Linux必学的重要命令教程

Linux必学的重要命令 ─────Linux命令 我们把Linux命令按照在系统中的作用分成几个部分分别予以介绍。但是,还有一些命令不好划分,然而学习它们同样是比较重要的。 Linux的命令行方式功能强大,如果熟练掌握了Linux的常用命令,往往只需要通过各种技巧就可以组合构成一条复杂的命令,从而完成用户任务。 内容基础,语言简短简洁 红联Linux论坛是致力于Linux技术讨论的站点,目前网站收录的文章及教程基本能满足不同水平的朋友学习。 红联Linux门户: https://www.doczj.com/doc/e22944376.html, 红联Linux论坛: https://www.doczj.com/doc/e22944376.html,/bbs 红联Linux 论坛大全,所有致力点都体现在这 https://www.doczj.com/doc/e22944376.html,/bbs/rf/linux/07.htm

目录 Linux必学的重要命令 tar unzip gunzip unarj mtools man unencode uudecode 在Linux命令行下发送邮件 实现tar的分卷 连续执行一个命令 用tar命令导出一个文件 用tar打包一个目录时只备份其中的几个子目录 Linux必学的命令结语 海量Linux技术文章

Linux必学的重要命令 发布时间:2006-11-16 12:33:28 我们把Linux命令按照在系统中的作用分成几个部分分别予以介绍。但是,还有一些命令不好划分,然而学习它们同样是比较重要的。

tar 发布时间:2006-11-16 12:34:06 1.作用 tar命令是Unix/Linux系统中备份文件的可靠方法,几乎可以工作于任何环境中,它的使用权限是所有用户。2.格式 tar [主选项+辅选项] 文件或目录 3.主要参数 使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用。 主选项: -c 创建新的档案文件。如果用户想备份一个目录或是一些文件,就要选择这个选项。 -r 把要存档的文件追加到档案文件的未尾。例如用户已经做好备份文件,又发现还有一个目录或是一些文件忘记备份了,这时可以使用该选项,将忘记的目录或文件追加到备份文件中。 -t 列出档案文件的内容,查看已经备份了哪些文件。 -u 更新文件。就是说,用新增的文件取代原备份文件,如果在备份文件中找不到要更新的文件,则把它追加到备份文件的最后。 -x 从档案文件中释放文件。 辅助选项: -b 该选项是为磁带机设定的,其后跟一数字,用来说明区块的大小,系统预设值为20(20×512 bytes)。 -f 使用档案文件或设备,这个选项通常是必选的。 -k 保存已经存在的文件。例如把某个文件还原,在还原的过程中遇到相同的文件,不会进行覆盖。 -m 在还原文件时,把所有文件的修改时间设定为现在。 -M 创建多卷的档案文件,以便在几个磁盘中存放。 -v 详细报告tar处理的文件信息。如无此选项,tar不报告文件信息。 -w 每一步都要求确认。 -z 用gzip来压缩/解压缩文件,加上该选项后可以将档案文件进行压缩,但还原时也一定要使用该选项进行解压缩。 4.应用说明 tar是Tape Archive(磁带归档)的缩写,最初设计用于将文件打包到磁带上。如果下载过Linux的源代码,或许已经碰到过tar文件。tar是一个基于文件的命令,它本质上是连续地、首尾相连地堆放文件。使用tar可以打包整个目录树,这使得它特别适合用于备份。归档文件可以全部还原,或者从中展开单独的文件和目录。备份可以保存到基于文件的设备或磁带设备上。文件可以在还原时重定向,以便将它们重新放到一个与最初保存它们的目录(或系统)不同的目录(或系统)。tar与文件系统无关,可以使用在ext2、ext3、JFS、Reiser和其它文件系统上。它支持各种备份介质,包括软盘、光盘写入器、可重写的光盘、JazZip、磁带、高端磁带等。Linux中以.tar结尾的文件都是用tar创建的。它的使用超出了单纯的备份,可用来把许多不同文件放到一起组成一个易于分开的文件。如果使用Linux源代码安装程序,一定使用过tar文件。这是一个基于文件的命令,它本质上是连续地、首尾相连地堆放文件。tar官方网址是https://www.doczj.com/doc/e22944376.html,/software/tar/tar.html。 请注意,不要忘了Linux是区分大小写的。例如,tar命令应该总是以小写的形式执行。命令行开关可以是大写、小写或大小写的混合。例如,-t和-T执行不同的功能。文件或目录名称可以混合使用大小写,而且就像命令和命令行开关一样是区分大小写的。

DOS命令教程(图文)

DOS 概述及入门 ——DOS简介现在家用电脑的操作系统大多都是用的Windows 95,但在1995年Windows 95推出以前,占统治地位的操作系统是DOS(Disk Operation System 磁盘操作系统)。 接触电脑早一点的人想必都听说过DOS的大名,更有很多人到今天仍然对DOS时代怀念不已,虽然自己的电脑早已用上了Windows 95,但仍要在硬盘上保留一份DOS,以备不时之需。 那么DOS的魅力到底在哪里呢?我们这就一起来揭开DOS的神秘面纱。 DOS 概述及入门 ——DOS的特点在DOS环境下,开机后,我们面对的不是桌面和图标,而是这样的电脑屏幕:这个C:\>叫做提示符,这个闪动的横线叫做光标。这样就表示电脑已经准备好,在等待我们给它下命令了。我们现在所需要做的,就是对电脑发出命令,给电脑什么命令,电脑就会做什么。那我们又怎么向电脑发布命令呢?

很简单。比如,我们想看看现在几点钟了,就可以输入时间命令,敲入time四个字母,它在英文中是“时间”的意思,再敲回车键加以确认,这时屏幕上就显示出当前时间。 再敲回车键,瞧!又出现提示符了,就可以输入下一条命令了。 如果想看日期,输入date,然后敲回车键确认。 这时屏幕上显示出当前日期。再敲回车键就回到提示符下。 这就是DOS的命令输入方法,和Windows 95中用鼠标寻找图标来运行程序不同,DOS中是通过输入英文命令加回车键这种方式来执行程序的。 怎么样,和Windows 95完全不一样吧?在字符界面下,我们只能通过键盘输入字符来指挥电脑工作,电脑完成一个命令后,出现下一个提示符,我们就又可以给电脑下命令了。注意,在DOS下电脑一次只能做一件事,做完以后才能开始下一件事;而在95下,我们可能让

命令行Makefile和make命令讲解教程

.命令行Makefile和make命令讲解教程 我们知道make是Linux下的一款程序自动维护工具,配合makefile的使用,就能够根据程序中模块的修改情况,自动判断应该对那些模块重新编译,从而保证软件是由最新的模块构成。本文分为上下两部分,我们将紧紧围绕make在软件开发中的应用展开详细的介绍。 一、都是源文件太多惹得祸 当我们在开发的程序中涉及众多源文件时,常常会引起一些问题。首先,如果程序只有两三个源文件,那么修改代码后直接重新编译全部源文件就行了,但是如果程序的源文件较多,这种简单的处理方式就有问题了。 设想一下,如果我们只修改了一个源文件,却要重新编译所有源文件,那么这显然是在浪费时间。其次,要是只重新编译那些受影响的文件的话,我们又该如何确定这些文件呢?比如我们使用了多个头文件,那么它们会被包含在各个源文件中,修改了某些头文件后,那些源文件受影响,哪些与此无关呢?如果采取拉网式大检查的话,可就费劲了。 由此可以看出,源文件多了可真是件让人头疼的事。幸运的是,实用程序make可以帮我们解决这两个问题——当程序的源文件改变后,它能保证所有受影响的文件都将重新编译,而不受影响的文件则不予编译,这真是太好了。 二、Make程序的命令行选项和参数 我们知道,make程序能够根据程序中各模块的修改情况,自动判断应对哪些模块重新编译,保证软件是由最新的模块构建的。至于检查哪些模块,以及如何构建软件由makefile文件来决定。 虽然make可以在makefile中进行配置,除此之外我们还可以利用make程序的命令行选项对它进行即时配置。Make命令参数的典型序列如下所示: make [-f makefile文件名][选项][宏定义][目标]

CMD命令行高级教程精选合编

CMD命令行高级教程精选合编 第一章批处理基础 第一节常用批处理内部命令简介 1、REM 和:: 2、ECHO 和@ 3、PAUSE 4、ERRORLEVEL 5、TITLE 6、COLOR 7、mode 配置系统设备 8、GOTO 和: 9、FIND 10、START 11、assoc 和ftype 12、pushd 和popd 13、CALL 14、shift 15、IF 16、setlocal 与变量延迟(ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION 启动或停用延缓环境变量扩展名。) 17、ATTRIB 显示或更改文件属性 第二节常用特殊符号 1、@ 命令行回显屏蔽符 2、% 批处理变量引导符 3、> 重定向符 4、>> 重定向符 5、<、>&、<& 重定向符 6、| 命令管道符 7、^ 转义字符 8、& 组合命令 9、&& 组合命令 10、|| 组合命令 11、"" 字符串界定符 12、, 逗号 13、; 分号 14、() 括号 15、! 感叹号 第二章FOR命令详解 一、基本格式 二、参数/d 仅为目录 三、参数/R 递归(文件名) 四、参数/L 迭代数值范围

五、参数/F 迭代及文件解析 第三章FOR命令中的变量 一、~I - 删除任何引号("),扩展%I 二、%~fI - 将%I 扩展到一个完全合格的路径名 三、%~dI - 仅将%I 扩展到一个驱动器号 四、%~pI - 仅将%I 扩展到一个路径 五、%~nI - 仅将%I 扩展到一个文件名 六、%~xI - 仅将%I 扩展到一个文件扩展名 七、%~sI - 扩展的路径只含有短名 八、%~aI - 将%I 扩展到文件的文件属性 九、%~tI - 将%I 扩展到文件的日期/时间 十、%~zI - 将%I 扩展到文件的大小 十一、%~$PATH:I 第四章批处理中的变量 一、系统变量 二、自定义变量 第五章set命令详解 一、用set命令设置自定义变量 二、用set命令进行简单计算 三、用set命令进行字符串处理 1、字符串替换 2、字符串截取 第六章if命令讲解 第一种用法:IF [NOT] ERRORLEVEL number command 第二种用法:IF [NOT] string1==string2 command 第三种用法:IF [NOT] EXIST filename command 第四种用法:IF增强的用法 第七章DOS编程高级技巧 一、界面设计 二、if…else…条件语句 三、循环语句 四、子程序 五、用ftp命令实现自动下载 六、用7-ZIP实现命令行压缩和解压功能 七、调用VBScript程序 八、将批处理转化为可执行文件 九、时间延迟 1、利用ping命令延时 2、利用for命令延时 3、利用vbs延迟函数,精确度毫秒,误差1000毫秒内 4、仅用批处理命令实现任意时间延迟,精确度10毫秒,误差50毫秒内 十、模拟进度条 十一、特殊字符的输入及应用 十二、随机数(%random%)的应用技巧

Linux系统命令及其使用详细讲解----经典教程

Linux系统命令及其使用详解 经典教程 cat cd chmod chown cp cut 名称:cat 使用权限:所有使用者 使用方式:cat [-AbeEnstTuv] [--help] [--version] fileName 说明:把档案串连接后传到基本输出(萤幕或加 > fileName 到另一个档案) 参数: -n 或 --number 由 1 开始对所有输出的行数编号 -b 或 --number-nonblank 和 -n 相似,只不过对于空白行不编号 -s 或 --squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行 -v 或 --show-nonprinting 例: cat -n textfile1 > textfile2 把 textfile1 的档案容加上行号后输入 textfile2 这个档案里 cat -b textfile1 textfile2 >> textfile3 把 textfile1 和 textfile2 的档案容加上行号(空白行不加)之后将容附加到 textfile3 名称:cd 使用权限:所有使用者 使用方式:cd [dirName] 说明:变换工作目录至 dirName。其中 dirName 表示法可为绝对路径或相对路径。若目录名称省略,则变换至使用者的 home directory (也就是刚 login 时所在的目录).另外,"~" 也表示为 home directory 的意思,"." 则是表示目前所在的目录,".." 则表示目前目录位置的上一层目录。 例:跳到 /usr/bin/: cd /usr/bin 跳到自己的 home directory: cd ~ 跳到目前目录的上上两层: cd ../.. 指令名称:chmod 使用权限:所有使用者 使用方式:chmod [-cfvR] [--help] [--version] mode file... 说明:Linux/Unix 的档案存取权限分为三级:档案拥有者,群组,其他。利用 chmod 可以藉以控制档案如何被他人所存取。 把计:

CMD基础教程

BAT批处理基础教程 DOS批处理高级教程精选合编--教程目录 第一章批处理基础 第一节常用批处理内部命令简介 1、REM 和:: 2、ECHO 和@ 3、PAUSE 4、ERRORLEVEL 5、TITLE 6、COLOR 7、mode 配置系统设备 8、GOTO 和: 9、FIND 10、START 11、assoc 和ftype 12、pushd 和popd 13、CALL 14、shift 15、IF 16、setlocal 与变量延迟 第二节常用特殊符号 1、@ 命令行回显屏蔽符 2、% 批处理变量引导符 3、> 重定向符 4、>> 重定向符 5、<、>&、<& 重定向符 6、| 命令管道符 7、^ 转义字符 8、& 组合命令 9、&& 组合命令 10、|| 组合命令 11、"" 字符串界定符 12、, 逗号 13、; 分号 14、() 括号 15、! 感叹号 第二章FOR命令详解 一、参数/d 二、参数/R 三、参数/L 四、参数/F 第三章FOR命令中的变量 一、~I - 删除任何引号("),扩展%I

二、%~fI - 将%I 扩展到一个完全合格的路径名 三、%~dI - 仅将%I 扩展到一个驱动器号 四、%~pI - 仅将%I 扩展到一个路径 五、%~nI - 仅将%I 扩展到一个文件名 六、%~xI - 仅将%I 扩展到一个文件扩展名 七、%~sI - 扩展的路径只含有短名 八、%~aI - 将%I 扩展到文件的文件属性 九、%~tI - 将%I 扩展到文件的日期/时间 十、%~zI - 将%I 扩展到文件的大小 十一、%~$PATH:I 第四章批处理中的变量 一、系统变量 二、自定义变量 第五章set命令详解 一、用set命令设置自定义变量 二、用set命令进行简单计算 三、用set命令进行字符串处理 1、字符串替换 2、字符串截取 第六章if命令讲解 第一种用法:IF [NOT] ERRORLEVEL number command 第二种用法:IF [NOT] string1==string2 command 第三种用法:IF [NOT] EXIST filename command 第四种用法:IF增强的用法 第七章DOS编程高级技巧 一、界面设计 二、if…else…条件语句 三、循环语句 四、子程序 五、用ftp命令实现自动下载 六、用7-ZIP实现命令行压缩和解压功能 七、调用VBScript程序 八、将批处理转化为可执行文件 九、时间延迟 十、模拟进度条 第一章批处理基础 第一节常用批处理内部命令简介 批处理定义:顾名思义,批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BA T或者CMD。这些命令统称批处理命令。https://www.doczj.com/doc/e22944376.html, 小知识:可以在键盘上按下Ctrl+C组合键来强行终止一个批处理的执行过程。 了解了大概意思后,我们正式开始学习.先看一个简单的例子! @echo off

CMD命令行高级教程精选合编

CMD命令行高级教程精选合编

目录 CMD命令行高级教程精选合编 (1) 第一章批处理基础 (5) 第一节常用批处理内部命令简介 (5) 1、REM 和:: (5) 2、ECHO 和@ (6) 3、PAUSE (7) 4、errorlevel (7) 5、title (7) 6、COLOR (7) 7、mode 配置系统设备 (8) 8、GOTO 和: (8) 9、find (9) 10、start 命令 (10) 11、assoc 和ftype (10) 12、pushd 和popd (10) 13、CALL (10) 14、shift (12) 15、IF (12) 16、setlocal 与变量延迟 (13) 17、ATTRIB 显示或更改文件属性 (15) 第二节常用特殊符号 (15) 1、@ 命令行回显屏蔽符 (16) 2、% 批处理变量引导符 (16) 3、>重定向符 (17) 4、>>重定向符 (17) 5、<、>&、<&重定向符 (17) 6、| 命令管道符 (18) 7、^ 转义字符 (18) 8、&组合命令 (18) 9、&&组合命令 (19) 10、|| 组合命令 (19) 11、"" 字符串界定符 (19) 12、, 逗号 (19) 13、; 分号 (19) 14、() 括号 (20) 15、! 感叹号 (20) 第二章DOS循环:for命令详解 (20) 一、基本格式 (21) 二、参数/d (21) 三、参数/R (21)

四、参数/L (22) 五、参数/F (23) 第三章FOR命令中的变量 (25) 一、~I (25) 二、%~fI (26) 三、%~dI (26) 四、%~pI (27) 五、%~nI (27) 六、%~xI (27) 七、%~sI (27) 八、%~aI (27) 九、%~tI (28) 十、%~zI (28) 十一、%~$PATH:I (28) 第四章批处理中的变量 (28) 一、系统变量 (28) 二、自定义变量 (31) 第五章set命令详解 (32) 一、用set命令设置自定义变量 (32) 二、用set命令进行简单计算 (33) 三、用set命令进行字符串处理 (35) 1、字符串替换 (35) 2、字符串截取 (36) 第六章if命令讲解 (38) 第一种用法: (39) 第二种用法: (41) 第三种用法: (41) 第四种用法: (42) 第七章DOS编程高级技巧 (43) 一、交互界面设计 (43) 二、if...else...条件语句.. (44) 三、循环语句 (45) 1、指定次数循环 (45) 2、对某集合执行循环语句。 (45) 3、条件循环 (45) 四、子程序 (46) 五、用ftp命令实现自动下载 (47) 六、用7-ZIP实现命令行压缩和解压功能 (47) 七、调用VBScript程序 (49) 八、将批处理转化为可执行文件: (49) 九、时间延迟 (50) 1、利用ping命令延时 (50) 2、利用for命令延时 (50) 3、利用vbs延迟函数 (50)

相关主题
文本预览
相关文档 最新文档