Skip to content

Makefile生成静态/动态库

场景构建

创建 test_lib 文件夹,在文件夹内创建并编写源文件、头文件以及 Makefile 文件

shell
touch Makefile  Makefile.config  test1.c  test2.c  test.h

各个文件内容如下

makefile
CC = gcc
RM = rm -f
makefile
# 引入配置文件
include Makefile.config

src = $(wildcard ./*.c)
object = $(patsubst %.c, %.o, $(src))

libtest:
	$(CC) -c $(src)
	$(AR) -r libtest.a $(object)
	$(RM) *.o

.PHONY:clean
clean:
	$(RM) *.a
c
#ifndef __SYSS_TEST_H__
#define __SYSS_TEST_H__

#include <stdio.h>

void test1();
void test2();

#endif // __SYSS_TEST_H__
c
#include "test.h"
#include <stdio.h>

void test1() {
    printf("call test1()\n");
}
c
#include "test.h"
#include <stdio.h>

void test2() {
    printf("call test2()\n");
}

生成静态库

shell
  test_lib ls
Makefile        Makefile.config test.h          test1.c         test2.c
  test_lib make
gcc -c ./test1.c ./test2.c
ar -r libtest.a  ./test1.o  ./test2.o
ar: creating archive libtest.a
rm -f *.o
  test_lib ls
Makefile        Makefile.config libtest.a       test.h          test1.c         test2.c
  test_lib

测试使用静态库

创建main.c并使用静态库

shell
touch main.c
c
#include "test.h"

int main() {
    test1();
    test2();

    return 0;
}
shell
  test_lib ls
Makefile        Makefile.config libtest.a       test.h          test1.c         test2.c
  test_lib touch main.c
  test_lib gcc main.c -o main -ltest -L ./
  test_lib ./main 
call test1()
call test2()
  test_lib

生成动态库

将上面生成静态库的几个文件复用一下,修改 Makefile 为以下内容

makefile
# 引入配置文件
include Makefile.config

src = $(wildcard ./*.c)
object = $(patsubst %.c, %.o, $(src))

libtest:
    $(CC) -fpic -c $(src)
    $(CC) -shared $(object) -o libtest.so
    $(RM) *.o

.PHONY:clean
clean:
    $(RM) *.so
shell
test_lib_so$ ls
Makefile  Makefile.config  test1.c  test2.c  test.h
test_lib_so$ make
gcc -fpic -c ./test1.c ./test2.c
gcc -shared  ./test1.o  ./test2.o -o libtest.so
rm -f *.o
test_lib_so$ ls
libtest.so  Makefile  Makefile.config  test1.c  test2.c  test.h
test_lib_so$

再复用一下之前的 main.c

shell
test_lib_so$ gcc main.c -ltest -L ./ -o main
/usr/bin/ld: /tmp/ccSjvEKB.o: in function `main':
main.c:(.text+0x9): undefined reference to `test1()'
/usr/bin/ld: main.c:(.text+0xe): undefined reference to `test2()'
collect2: error: ld returned 1 exit status

不出意外的报错了,设置当前路径到当前用户的系统变量

shell
vim ~/.bashrc

# 打开文件以后在末尾添加下面这一句
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/code/makefile/test_lib_so/

#注意需要有$LD_LIBRARY_PATH: 不然这个路径会直接覆盖原有的

#添加完 esc :wq
# 回到 shell 以后使配置生效
. ~/.bashrc

# 再次进行编译
test_lib_so$ gcc main.c -ltest -L ./ -o main
test_lib_so$

编译成功以后运行测试

shell
test_lib_so$ ./main 
call test1()
call test2()
test_lib_so$