使用 Makefile 从现有文件创建(.so)文件

5
我有4个文件:1.c,1.h,2.c和2.h。 我需要一个 makefile 文件,可以从这 4 个文件中创建一个动态库(.so)。 我尝试编写类似于以下代码的 makefile: library.so : 1.c 1.h 2.c 2.h
但是它并没有起作用。如果有人能帮助我,那就太好了。谢谢。

它们是头文件 - 不是 .so 文件的一部分。 - Ed Heal
那么我的Makefile应该长什么样子? - user2581733
4个回答

8

类似于某事

 CC=gcc
 CFLAGS= -Wall -g -O -fPIC
 RM= rm -f
 .PHONY: all clean

 all: library.so
 clean:
      $(RM) *.o *.so

 library.so: 1.o 2.o
      $(LINK.c) -shared $^ -o $@

 1.o: 1.c 1.h 2.h

 2.o: 2.c 1.h 2.h

但这是未经测试的!我假定您使用具有GNU make和仅包含库源代码的目录(带有上面的Makefile),这可能不是一个好的做法 - 您可能需要一个测试用例 - (您可以针对%.c或其他方式设置特殊的Makefile规则以获得%.pic.o)。

提示:使用make -p了解内置规则。然后使用make --trace或(使用remakeremake -x更好地了解make正在做什么。

还请参阅Drepper's paper:How to Write Shared LibrariesGNU make文档程序库HowTo这个答案,...


1
这里有个打字错误,应该是$<而不是$^。 - Feng Zhang

8
最简单的方法是:
CXXFLAGS += -fPIC
CXXFLAGS += -O3
x.so: 1.o 2.o
    $(LINK.cc) -shared $^ $(LOADLIBS) $(LDLIBS) -o $@

略微进阶一点:
CC    = gcc
FLAGS        = # -std=gnu99 -Iinclude
CFLAGS       = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS      = -shared

DEBUGFLAGS   = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program

TARGET  = example.so
SOURCES = $(wildcard *.c)
HEADERS = $(wildcard *.h)
OBJECTS = $(SOURCES:.c=.o)


all: $(TARGET)

$(TARGET): $(OBJECTS)
        $(CC) $(FLAGS) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(OBJECTS)

1
不要使用 $(shell echo ./*.c),而是使用 $(wildcard *.c) - Basile Starynkevitch
好的,非常感谢。我希望我能提高您的声誉,但不幸的是,我太新了,无法做到这一点 :( - user2581733
你在最后一行忘记使用LDFLAGS,导致gcc报错,说没有main()函数,但在共享库中可能没有main()函数... - pulse

3
CC = gcc                                # C compiler
CFLAGS = -fPIC -Wall -Wextra -g         # C flags
LDFLAGS = -shared                       # linking flags
RM = rm -f                              # rm command
TARGET_LIB = sh_main.so                 # target lib

SRCS = add.c sub.c main.c               # source file
DEPS = header.h                         # header file
OBJS = $(SRCS:.c=.o)                    # object file

.PHONY: all
all: ${TARGET_LIB}

$(TARGET_LIB): $(OBJS)
        $(CC) ${LDFLAGS} -o $@ $^       # -o $@ says, put the output of the compilation in the file named on the left side of the :

$(SRCS:.c=.d):%.d:%.c
        $(CC) $(CFLAGS) -MM $< >$@      # the $< is the first item in the dependencies list, and the CFLAGS macro is defined as above
include $(SRCS:.c=.d)

.PHONY: clean
clean:
        -${RM} ${TARGET_LIB} ${OBJS} $(SRCS:.c=.d)

共享库创建成功后,需要进行安装。
以root用户身份登录。
将共享库复制到标准目录/usr/lib中。
运行ldconfig命令。

使用共享库重新编译您的.c文件。 root@Admin:~/C/SharedLibrary# gcc -c main.c root@Admin:~/C/SharedLibrary# gcc -o main main.o sh_main.so

root@Admin:~/C/SharedLibrary# ldd main

注意:在我的情况下,
main.c:主C文件,
sh_main.so:共享库。


为什么要重新编译?只是因为/usr/lib通常是由root chown的吗?还是因为...无论如何,这为同样的问题提供了成功的模板。我还没有重新编译。 - Chris

0

我不是 GNU Make 的专家,但这看起来对我来说是合理的。

CFLAGS+=-fPIC
%.so: ; $(LINK.c) $(LDFLAGS) -shared $^ -o $@

library.so: 1.o 2.o  # default target first

# changes to `1.h` imply `1.o` needs to be rebuilt
1.o: 1.h  
2.o: 2.h

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接