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 $@ $^