编译工具有很多(make/cmake/BJam)。如果不考虑跨平台的话,还是make比较方便。使用make编译需要编写Makefile。本文编写Makefile来生成C/C++静态库。
Makefile文件首先是一个文本文件,Linux下默认有两种命名方式:
在工程目录下运行make命令,make程序先找makefile,如果没有makefile再找Makefile文件。也就是说如果makefile和Makefile两个文件都存在默认使用makefile。
其实Makefile的文件名可以是任意的,例如Buildfile,可以使用下面命令编译:
make -f BuildFile
本文使用make程序版本:
$make --version
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
这里以CppTest库代码为例,代码目录结构:
cpptest$ tree
.
├── Makefile
├── inc
│ ├── cpptest-assert.h
│ ├── cpptest-collectoroutput.h
│ ├── cpptest-compileroutput.h
│ ├── cpptest-htmloutput.h
│ ├── cpptest-output.h
│ ├── cpptest-source.h
│ ├── cpptest-suite.h
│ ├── cpptest-textoutput.h
│ ├── cpptest-time.h
│ └── cpptest.h
└── src
├── collectoroutput.cpp
├── compileroutput.cpp
├── config.h
├── htmloutput.cpp
├── missing.cpp
├── missing.h
├── source.cpp
├── suite.cpp
├── textoutput.cpp
├── time.cpp
├── utils.cpp
├── utils.h
└── winconfig.h
2 directories, 24 files
Makefile文件如下:
PROJECT_NAME ?= cpptest
CC ?= gcc
CXX ?= g++
AR ?= ar
CFLAGS :=
C++FLAGS := -std=c++11
LIBFLAGS := -rcD
PWD := $(shell pwd)
INCS := -I$(PWD)/inc
SRCDIR := $(PWD)/src
LIBDIR := $(PWD)/lib
LIBNAME := $(LIBDIR)/lib$(PROJECT_NAME).a
CSRC := $(wildcard $(SRCDIR)/*.c)
OBJS := $(patsubst %.c,%.o,$(CSRC))
CPPS := $(wildcard $(SRCDIR)/*.cpp)
CPPOBJS := $(patsubst %.cpp,%.o,$(CPPS))
all: $(OBJS) $(CPPOBJS) $(LIBDIR)
$(AR) $(LIBFLAGS) $(LIBNAME) $(OBJS) $(CPPOBJS)
$(OBJS): %.o:%.c
$(CC) -c $(CFLAGS) $(INCS) $< -o $@
$(CPPOBJS): %.o:%.cpp
$(CXX) -c $(C++FLAGS) $(INCS) $< -o $@
$(LIBDIR):
@mkdir $(LIBDIR) -p
.PHNOY:clean
clean:
@rm -f $(OBJS) $(CPPOBJS)
@rm -f $(LIBNAME)
编译结果:
cpptest$ make
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/utils.cpp -o /home/james/git/cpptest/src/utils.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/source.cpp -o /home/james/git/cpptest/src/source.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/time.cpp -o /home/james/git/cpptest/src/time.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/collectoroutput.cpp -o /home/james/git/cpptest/src/collectoroutput.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/textoutput.cpp -o /home/james/git/cpptest/src/textoutput.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/compileroutput.cpp -o /home/james/git/cpptest/src/compileroutput.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/htmloutput.cpp -o /home/james/git/cpptest/src/htmloutput.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/suite.cpp -o /home/james/git/cpptest/src/suite.o
g++ -c -std=c++11 -I/home/james/git/cpptest/inc /home/james/git/cpptest/src/missing.cpp -o /home/james/git/cpptest/src/missing.o
ar -rcD /home/james/git/cpptest/lib/libcpptest.a /home/james/git/cpptest/src/utils.o /home/james/git/cpptest/src/source.o /home/james/git/cpptest/src/time.o /home/james/git/cpptest/src/collectoroutput.o /home/james/git/cpptest/src/textoutput.o /home/james/git/cpptest/src/compileroutput.o /home/james/git/cpptest/src/htmloutput.o /home/james/git/cpptest/src/suite.o /home/james/git/cpptest/src/missing.o
说明:
PROJECT_NAME ?= cpptest
CC ?= gcc
CXX ?= g++
AR ?= ar
说明:
CFLAGS :=
C++FLAGS := -std=c++11
LIBFLAGS := -rcD
说明:
PWD := $(shell pwd)
INCS := -I$(PWD)/inc
SRCDIR := $(PWD)/src
LIBDIR := $(PWD)/lib
LIBNAME := $(LIBDIR)/lib$(PROJECT_NAME).a
说明:
CSRC := $(wildcard $(SRCDIR)/*.c)
OBJS := $(patsubst %.c,%.o,$(CSRC))
CPPS := $(wildcard $(SRCDIR)/*.cpp)
CPPOBJS := $(patsubst %.cpp,%.o,$(CPPS))
说明:
all: $(OBJS) $(CPPOBJS) $(LIBDIR)
$(AR) $(LIBFLAGS) $(LIBNAME) $(OBJS) $(CPPOBJS)
$(OBJS): %.o:%.c
$(CC) -c $(CFLAGS) $(INCS) $< -o $@
$(CPPOBJS): %.o:%.cpp
$(CXX) -c $(C++FLAGS) $(INCS) $< -o $@
$(LIBDIR):
@mkdir $(LIBDIR) -p
.PHNOY:clean
clean:
@rm -f $(OBJS) $(CPPOBJS)
@rm -f $(LIBNAME)
说明: