Linux Makefile

 Linux基础——gcc编译、静态库与动态库(共享库)_daidaihema的博客-CSDN博客_gcc编译链接静态库和动态库

 制定连接同名的动态库/静态库:

GCC同时使用静态库和动态库链接_believe的专栏-CSDN博客_gcc 动态库链接静态库

当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式。这时需要作用-Wl的方式:

gcc test.cpp -L. -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic -ltestdll 

另外还要注意系统的运行库使用动态连接的方式,所以当动态库在静态库前面连接时,必须在命令行最后使用动态连接的命令才能正常连接

,如:

gcc test.cpp -L. -Wl,-Bdynamic -ltestdll -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic

最后的-Wl,-Bdynamic表示将缺省库链接模式恢复成动态链接。

1. linux makefile中的一些函数语法:

利用Makefile给多文件、多目录C源码建立工程_一口Linux的专栏-CSDN博客


2. 所有的源文件和头文件在一个目录下

Linux平台Makefile文件的编写基础篇_chenguisheng86的专栏-CSDN博客

上一层楼:使用变量

       上面提到一句,如果要编译cpp文件,只要把gcc改成g++就行了。但如果Makefile中有很多gcc,那不就很麻烦了。

       第二个例子:

       === makefile 开始 ===
              OBJS = file1.o file2.o
              CC = gcc
              CFLAGS = -Wall -O -g

              helloworld : $(OBJS)
                     $(CC) $(OBJS) -o helloworld

              file1.o : file1.c file2.h
                     $(CC) $(CFLAGS) -c file1.c -o file1.o

              file2.o : file2.c file2.h
                     $(CC) $(CFLAGS) -c file2.c -o file2.o

              clean:

                     rm -rf *.o helloworld
=== makefile 结束 ===

       这里我们应用到了变量。要设定一个变量,你只要在一行的开始写下这个变量的名字,后 面跟一个 = 号,后面跟你要设定的这个变量的值。以后你要引用 这个变量,写一个 $ 符号,后面是围在括号里的变量名。

CFLAGS = -Wall -O –g,解释一下。这是配置编译器设置,并把它赋值给CFFLAGS变量。

-Wall:          输出所有的警告信息。

-O:              在编译时进行优化。

-g:               表示编译debug版本。

       这样写的Makefile文件比较简单,但很容易就会发现缺点,那就是要列出所有的c文件。如果你添加一个c文件,那就需要修改Makefile文件,这在项目开发中还是比较麻烦的。

再上一层楼:使用函数

       学到这里,你也许会说,这就好像编程序吗?有变量,也有函数。其实这就是编程序,只不过用的语言不同而已。

$@:表示编译的目标产物

$< : 第一个依赖项

$^:  所有的依赖项

       第三个例子:

       === makefile 开始 ===
              CC = gcc

              XX = g++
              CFLAGS = -Wall -O –g

              TARGET = ./helloworld

              %.o: %.c

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

              %.o:%.cpp

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

              SOURCES = $(wildcard *.c *.cpp)


              OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))


              $(TARGET) : $(OBJS)
                     $(XX) $(OBJS) -o $(TARGET)

                     chmod a+x $(TARGET)

clean:

       rm -rf *.o helloworld
=== makefile 结束 ===

 ///

函数1:wildcard

       产生一个所有以 '.c' 结尾的文件的列表。

       SOURCES = $(wildcard *.c *.cpp)表示产生一个所有以 .c,.cpp结尾的文件的列表然后存入变量 SOURCES 里。

函数2:patsubst

       匹配替换,有三个参数。第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的列表。

OBJS = $(patsubst %.c,  %.o,  $(patsubst %.cc,  %.o,  $(SOURCES)))

表示把文件列表中所有的.c,.cpp字符变成.o,形成一个新的文件列表,然后存入OBJS变量中。

%.o: %.c

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

%.o:%.cpp

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

       这几句命令表示把所有的.c,.cpp编译成.o文件。

       这里有三个比较有用的内部变量。$@ 扩展成当前规则的目的文件名,

$< 扩展成依靠列表中的第一个依靠文件,

而 $^ 扩展成整个依靠的列表(除掉了里面所有重 复的文件名)。

       chmod a+x $(TARGET)表示把helloworld强制变成可执行文件

ps:

上面所有的例子都假定所有的文件都在同一个目录下,不包括子目录。

       那么文件不在一个目录可以吗?

       怎么编写Makefile生成静态库?

2.1 教你写Makefile(很全,含有工作经验的)_心之所向-CSDN博客_如何写makefile

3. 多文件多目录编译

 好的博客!!!

多目录时Makefile 的编写方法_GeorgeGuo-CSDN博客_多目录makefile的编写实例

多子目录的makefile编译库模板_What the Fuck-CSDN博客

CUR_DIR=/home/xiaojie/Desktop/demo_multi_makefile/test3

ADD_DIR=${CUR_DIR}/add
SUB_DIR=${CUR_DIR}/sub
MUL_DIR=${CUR_DIR}/multis
MAIN_DIR=${CUR_DIR}/main

INC_DIR= -I${ADD_DIR} \
         -I${SUB_DIR} \
         -I${MUL_DIR} \
         -I${MAIN_DIR}

SRC = ${wildcard  ${ADD_DIR}/*.c} \
      ${wildcard  ${SUB_DIR}/*.c} \
      ${wildcard  ${MUL_DIR}/*.c} \
      ${wildcard  ${MAIN_DIR}/*.c}
OBJ = ${patsubst %.c, %.o, ${SRC}}

TARGET=main
CC=gcc
CCFLAGS=-g -Wall ${INC_DIR}


${TARGET}: ${OBJ}
    ${CC} ${OBJ} -o $@
    @echo "Compile done."

#${OBJ}:${SRC}
#   $(CC) ${CCFLAGS} -c $? 

$(OBJ):%.o:%.c
    @echo "Compiling $< ==> $@"
    ${CC} ${CCFLAGS} -c $< -o $@

clean:
    @rm -f ${OBJ}
    @echo "Clean object files done."

    @rm -f *~
    @echo "Clean tempreator files done."

    @rm -f ${TARGET}
    @echo "Clean target files done."

    @echo "Clean done."
#这是一个makefile的样例,用于编译多文件夹,多文件的编译

#编译工具链
CC	= gcc
CXX	= g++
LD	= $(CC)
AS	= nasm

#编译选项
ASFLAGS  = -m32
CFLAGS   = -m32 -Wall $(incdir)	 
CXXFLAGS = -m32 -Wall $(incdir)
LDFLAGS	 = -m32 -static

#定义输出文件名
target = main.exe

#定义源码目录
srcdir = src \
         src/dir1 \
         src/dir2 \
         src/dir2/sub1 \
         src/dir2/sub2

#定义包含目录
incdir = $(foreach dir,$(srcdir),-I$(dir))

#定义附加依赖库
inclib = -lpthread

#遍历所有dir,并搜索该dir下面的所有.c文件
allsrc = $(foreach dir,$(srcdir),$(wildcard $(dir)/*.c))

#把所有的.c替换为.o
allobj = $(allsrc:%.c=%.o)

#把所有的.c替换为.d
alldep = $(allsrc:%.c=%.d)

#生成.d的规则
%.d: %.c
	@echo Generating $@...
	@$(CC) -MM -MT "$(<D)/$(*F).o $@" $(CFLAGS) $< >$@
	
#生成.o的规则
%.o: %.c
	@echo Compiling $<...
	@$(CC) $(CFLAGS) -c $< -o $@


#如果不是第1次调用make,则包含所有.d文件	
ifneq ($(MAKELEVEL), 0)
include $(alldep)
endif

#声明虚拟目标
.PHONY:	init clean

init: $(alldep)
	@$(MAKE) -s $(target)

ifneq ($(MAKELEVEL), 0)
$(target): $(alldep) $(allobj)
	@echo Linking target...
	@$(LD) $(LDFLAGS) -o $@ $(allobj) $(inclib)
	@echo Link done!
endif

clean:
	@rm -rf $(alldep) $(allobj) $(target)
	@echo clean done.

LIB_SRC1 = ./src1
LIB_SRC2 = ./src2
LIB_A := libs.a

#VPATH = $(LIB_SRC1) $(LIB_SRC2)

SRC := $(wildcard $(LIB_SRC1)/*.c)
SRC += $(wildcard $(LIB_SRC2)/*.c)

OBJS := $(patsubst %.c,%.o,$(SRC))

CC:=gcc
CFLAGS:= -I./

.PNONY:all clean

all: $(LIB_A)

clean:
  @rm -f $(OBJS)
  @rm -f $(LIB_A) 

$(OBJS):%.o:%.c
  $(CC) -c $(CFLAGS) $^ -o $@

$(LIB_A):$(OBJS)
  @echo '$$OBJS'=$(OBJS)
  @echo '$$(SRC)/*.c'=$(SRC)
  @echo '$$@' = $@
  @echo '$$^' = $^
  @echo '$$<' = $<
  $(AR) rcv $@ $^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值