Linux make --强大的编译工具

用途说明

make命令是一个常用的编译命令,尤其是在开发C/C++程序时,它通过Makefile文件中描述的源程序之间的依赖关系来自动进行编译。Makefile文件是按照规定的格式编写的,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。在首次执行 make时,会将所有相关的文件都进行编译,而在以后make时,通常是进行增量编译,即只对修改过的源代码进行编译。许多Tarball格式的开源软 件,在解压之后,一般先执行./configure,然后执行make,再执行make install进行安装。在进行Java编译时,我们常用的是ant,这个ant工具的发明乃是由于Jamesmakefile的特殊格式弄烦了,采用 XML格式来描述任务之间的关系,但是ant工具借鉴了make工具的做法这是肯定的。

man make 写道

The purpose of themake utility is to determine automatically which pieces of a large program needto be recom-

piled, and issue thecommands to recompile them. The manual describes the GNU implementation ofmake, which

was written byRichard Stallman and Roland McGrath, and is currently maintained by Paul Smith.Our examples

show C programs,since they are most common, but you can use make with any programming languagewhose compiler

can be run with ashell command. In fact, make is not limited to programs. You can use it todescribe any

task where somefiles must be updated automatically from others whenever the others change.

 

To prepare to usemake, you must write a file called the makefile that describes therelationships among files

in your program, andthe states the commands for updating each file. In a program, typically theexecutable

file is updated fromobject files, which are in turn made by compiling source files.

 

Once a suitablemakefile exists, each time you change some source files, this simple shellcommand:

 

make

 

suffices to performall necessary recompilations. The make program uses the makefile data base andthe last-

modification timesof the files to decide which of the files need to be updated. For each of thosefiles, it

issues the commandsrecorded in the data base.

 

make executescommands in the makefile to update one or more target names, where name istypically a program.

If no -f option ispresent, make will look for the makefiles GNUmakefile, makefile, and Makefile,in that

order.

 

Normally you shouldcall your makefile either makefile or Makefile. (We recommend Makefile becauseit appears

prominently near thebeginning of a directory listing, right near other important files such asREADME.) The

first name checked,GNUmakefile, is not recommended for most makefiles. You should use this name ifyou have a

makefile that isspecific to GNU make, and will not be understood by other versions of make. Ifmakefile is

‘-’, the standardinput is read.

 

make updates atarget if it depends on prerequisite files that have been modified since thetarget was last

modified, or if thetarget does not exist.

使用make进行编译的关键点就是掌握makefile的编写规则,make的手册页中说道,makefile文件可以是GNUmakefile,makefile或者Makefile,但是推荐使用Makefile,因为在列出某个目录的文件时,使用Makefile作为文件名时将被排在前面。 makefile文件也像C/C++代码一样支持include方式,即把一些基本的依赖规则写在一个公共的文件中,然后其他makefile文件包含此 文件。我所使用的公共makefile文件名为common.mk,是多年以前从一个高人那儿拷贝而来的,现在贡献给大家。里面有些晦涩难懂的 makefile指令,但是对于使用者来说可以不必关注。思路就是将makefile所在目录的源程序找出来,然后按照依赖关系进行编译。

common.mk 写道

#This is the commonpart for makefile

 

SOURCE := $(wildcard*.c) $(wildcard *.cc) $(wildcard *.cpp)

OBJS := $(patsubst%.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SOURCE))))

DEPS := $(patsubst%.o,%.d,$(OBJS))

MISSING_DEPS :=$(filter-out $(wildcard $(DEPS)),$(DEPS))

CPPFLAGS += -MD

 

.PHONY : everythingobjs clean veryclean vc rebuild ct rl

 

everything :$(TARGETS)

 

objs : $(OBJS)

 

clean :

@$(RM) *.o

@$(RM) *.d

 

veryclean: clean

@$(RM) $(TARGETS)

@$(RM) cscope.out

@$(RM) core*

 

vc: veryclean

 

ct:

@$(RM) $(TARGETS)

 

rl: ct everything

 

rebuild: verycleaneverything

 

ifneq($(MISSING_DEPS),)

$(MISSING_DEPS) :

@$(RM) $(patsubst%.d,%.o,$@)

endif

 

-include $(DEPS)

怎么来使用这个common.mk来帮助我们编写makefile文件呢,首先我们来看一下编译成静态库的情况。见下面文件,其中的libhyfcd.a就是目标静态库文件的名称,INCS定义了依赖的包含文件路径。

makefile 写道

TARGETS = $(BIN1)

 

BIN1 = libhyfcd.a

BIN1_OBJS = $(OBJS)

BIN1_LIBS =

BIN1_LFLAGS =

INCS = -I..-I../../hycu2 -I/usr/include/mysql

 

#CC := g++

CC := gcc

CXX := gcc

CFLAGS := -g $(INCS)-Wall -D_REENTRANT -D__DECLSPEC_SUPPORTED -DOPENSSL_NO_KRB5 #-DNDEBUG

CXXFLAGS :=$(CFLAGS)

 

include common.mk

 

# $(BIN1) :$(BIN1_OBJS)

# $(CC) -g -o $@$(BIN1_LFLAGS) $^ $(addprefix -l,$(BIN1_LIBS))

 

$(BIN1):$(BIN1_OBJS)

ar rcs $@ $^

再来看一下编译成可执行文件的情况。见下面文件,其中msgc就是目标执行文件,BIN1_LIBS是依赖的库。

写道

TARGETS = $(BIN1)

 

BIN1 = msgc

BIN1_OBJS = $(OBJS)

BIN1_LIBS = cursespthread

BIN1_LFLAGS =#-L../hyfc/lib

INCS = #-I../hyfc

 

CC := g++

CFLAGS := -g $(INCS)-Wall

#CFLAGS := -g$(INCS) -Wall -DLOG_CHECK

#CFLAGS := -g$(INCS) -Wall #-DNDEBUG

CXXFLAGS :=$(CFLAGS)

 

include/usr/include/hyfc/common.mk

 

$(BIN1) :$(BIN1_OBJS)

$(CC) -g -o $@$(BIN1_LFLAGS) $^ $(addprefix -l,$(BIN1_LIBS))

 

补充(2011.08.07):列位看官,如果你关注的是Makefile的语法结构,那么不妨看参考资料【5】《GNUmake中文手册》。

 

常用参数

格式:make

使用默认的makefile文件进行编译,按照GNUmakefile,makefile和Makefile的顺序进行查找。编译目标all。

 

格式:make -fmakefile.debug

使用指定的makefile进行编译,此处就是makefile.debug。编译目标all。

 

格式:make install

编译目标install。通常用于安装软件。

 

格式:make clean

编译目标clean。通常用于清除目标文件.o。

 

格式:make veryclean

编译目标clean。通常用于清除目标文件.o以及执行文件等,意思是干净的清除掉除makefile和源程序之外的文件。

 

 

格式:make rl

编译目标rl。rl是relink的缩写,即重新链接,常用于某个依赖的库文件发生变化时强制重新链接生成执行文件。

 

使用示例

示例一 编译安装mysql++2.3.2的过程

[root@jfht setup]# ls mysql++-2.3.2.tar.gz

mysql++-2.3.2.tar.gz

[root@jfht setup]# tar zxf mysql++-2.3.2.tar.gz

[root@jfht setup]# cd mysql++-2.3.2

[root@jfhtmysql++-2.3.2]# ./configure --prefix=/usr

checking buildsystem type... i686-pc-linux-gnu

checking host systemtype... i686-pc-linux-gnu

checking targetsystem type... i686-pc-linux-gnu

checking for gcc...gcc

checking for Ccompiler default output file name... a.out

checking whether theC compiler works... yes

checking whether weare cross compiling... no

checking for suffixof executables...

checking for suffixof object files... o

checking whether weare using the GNU C compiler... yes

checking whether gccaccepts -g... yes

checking for gccoption to accept ANSI C... none needed

checking forranlib... ranlib

checking for aBSD-compatible install... /usr/bin/install -c

checking whether ln-s works... yes

checking whethermake sets $(MAKE)... yes

checking for ar...ar

checking forstrip... strip

checking for nm...nm

checking if make isGNU make... yes

checking fordependency tracking method... gcc

checking for gcc...(cached) gcc

checking whether weare using the GNU C compiler... (cached) yes

checking whether gccaccepts -g... (cached) yes

checking for gccoption to accept ANSI C... (cached) none needed

checking how to runthe C preprocessor... gcc -E

checking foregrep... grep -E

checking for ANSI Cheader files... yes

checking forsys/types.h... yes

checking forsys/stat.h... yes

checking forstdlib.h... yes

checking forstring.h... yes

checking formemory.h... yes

checking forstrings.h... yes

checking forinttypes.h... yes

checking forstdint.h... yes

checking forunistd.h... yes

checking zlib.husability... yes

checking zlib.hpresence... yes

checking forzlib.h... yes

checking for gzreadin -lz... yes

checking whether -lmis needed to use C math functions... no

checking whether-lsocket is needed... no

checking whether-lnsl is needed... no

checking for MySQLlibrary directory... /usr/lib

checking for MySQLinclude directory... /usr/include/mysql

checking formysql_store_result in -lmysqlclient... yes

checking formysql_ssl_set in -lmysqlclient... yes

checking forlocaltime_r()... yes

checking for main in-lintl... no

checking for g++...g++

checking whether weare using the GNU C++ compiler... yes

checking whether g++accepts -g... yes

checking for STLslist extension... <ext/slist>, namespace __gnu_cxx

configure: creating./config.status

config.status:creating Makefile

config.status:creating mysql++.spec

config.status:creating lib/Doxyfile

config.status:creating lib/mysql++.h

config.status:creating config.h

[root@jfhtmysql++-2.3.2]# make && make install

此处省略较多输出。

/usr/bin/install -c-d /usr/lib

/usr/bin/install -c-m 644 libmysqlpp.so /usr/lib

/usr/bin/install -clibmysqlpp.so.2.3.2 /usr/lib

(cd /usr/lib ; rm -flibmysqlpp.so libmysqlpp.so.2; ln -s libmysqlpp.so.2.3.2 libmysqlpp.so.2; ln -slibmysqlpp.so.2 libmysqlpp.so)

/usr/bin/install -c-d /usr/include/mysql++

(cd . ;/usr/bin/install -c -m 644  lib/*.h /usr/include/mysql++)

[root@jfhtmysql++-2.3.2]#

 

示例二 使用common.mk进行编译的例子

[root@jfht src]# make

make: Nothing to bedone for `everything'.

[root@jfht src]# make clean

[root@jfht src]# make

g++ -g -Wall  -MD  -c -o compiler.o compiler.cpp

g++ -g -Wall  -MD  -c -o file_updater.o file_updater.cpp

g++ -g -Wall  -MD  -c -o file_util.o file_util.cpp

g++ -g -Wall  -MD  -c -o gen_async.o gen_async.cpp

g++ -g -Wall  -MD  -c -o gen_c.o gen_c.cpp

g++ -g -Wall  -MD  -c -o gen_cpp.o gen_cpp.cpp

g++ -g -Wall  -MD  -c -o gen_fmdo2.o gen_fmdo2.cpp

g++ -g -Wall  -MD  -c -o gen_fmdo.o gen_fmdo.cpp

g++ -g -Wall  -MD  -c -o gen_hyfc.o gen_hyfc.cpp

g++ -g -Wall  -MD  -c -o gen_hyfcw.o gen_hyfcw.cpp

g++ -g -Wall  -MD  -c -o gen_java.o gen_java.cpp

g++ -g -Wall  -MD  -c -o gen_jdom.o gen_jdom.cpp

g++ -g -Wall  -MD  -c -o gen_jt.o gen_jt.cpp

g++ -g -Wall  -MD  -c -o gen_jxh.o gen_jxh.cpp

g++ -g -Wall  -MD  -c -o gen_pas.o gen_pas.cpp

g++ -g -Wall  -MD  -c -o gen_php.o gen_php.cpp

g++ -g -Wall  -MD  -c -o gen_struts.o gen_struts.cpp

g++ -g -Wall  -MD  -c -o gen_tag.o gen_tag.cpp

g++ -g -Wall  -MD  -c -o gen_udpsw.o gen_udpsw.cpp

g++ -g -Wall  -MD  -c -o gen_wsdl.o gen_wsdl.cpp

g++ -g -Wall  -MD  -c -o gen_xml.o gen_xml.cpp

g++ -g -Wall  -MD  -c -o msgc.o msgc.cpp

g++ -g -Wall  -MD  -c -o string_util.o string_util.cpp

g++ -g -o msgc compiler.o file_updater.o file_util.o gen_async.o gen_c.o gen_cpp.o gen_fmdo2.ogen_fmdo.o gen_hyfc.o gen_hyfcw.o gen_java.o gen_jdom.o gen_jt.o gen_jxh.ogen_pas.o gen_php.o gen_struts.o gen_tag.o gen_udpsw.o gen_wsdl.o gen_xml.o msgc.ostring_util.o -lcurses -lpthread

cp -af msgc /usr/bin

cp -af msgcmsgc.`uname -r`

[root@jfht src]# make rl

g++ -g -o msgc compiler.o file_updater.o file_util.o gen_async.o gen_c.o gen_cpp.o gen_fmdo2.ogen_fmdo.o gen_hyfc.o gen_hyfcw.o gen_java.o gen_jdom.o gen_jt.o gen_jxh.ogen_pas.o gen_php.o gen_struts.o gen_tag.o gen_udpsw.o gen_wsdl.o gen_xml.o msgc.ostring_util.o -lcurses -lpthread

cp -af msgc /usr/bin

cp -af msgcmsgc.`uname -r`

[root@jfht src]#


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译 JDK16 需要使用比较强大的机器和耐心,整个编译过程可能需要数小时或数天的时间。以下是使用 `aarch64-linux-android23-clang` 工具编译 JDK16 的详细步骤: 1. 下载和安装 Android NDK 在官网上下载并安装 Android NDK,安装完成后设置环境变量 `ANDROID_NDK_HOME`,指向 NDK 的安装目录。 2. 下载和解压 JDK16 源码 在官网上下载并解压 JDK16 的源代码包,进入解压后的目录。 3. 配置编译环境 进入 `make` 目录,执行以下命令来生成编译环境的配置文件: ``` bash configure \ --with-boot-jdk=$JAVA_HOME \ --with-toolchain-type=clang \ --openjdk-target=aarch64-linux-android \ --with-cxx-compiler=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android23-clang++ \ --with-cc=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android23-clang \ --with-debug-level=slowdebug \ --disable-warnings-as-errors ``` 其中,`$JAVA_HOME` 为你本地已经安装的 JDK 路径。 4. 编译 执行以下命令进行编译: ``` make images ``` 如果编译过程中出现错误,可以尝试执行以下命令进行清理和重新编译: ``` make clean make images ``` 5. 安装 编译完成后,在 `build/images/jdk` 目录下会生成可执行文件和库文件。将这些文件拷贝到目标设备上,并设置相应的环境变量即可使用。 以上是使用 `aarch64-linux-android23-clang` 工具编译 JDK16 的大致步骤,具体细节需要根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值