1

我正在尝试将我的程序转换为使用插件,但我在使用 Makefile 时遇到了一些问题。我希望 Makefile 在目录插件中查找,编译在那里找到的所有具有两个不同扩展名 .so 和 .o 的 .c 文件,最好将其编译到一个单独的文件夹中。基本上和这个一样:

gcc -shared -lc -o testPugin.so testPugin.o
gcc -c -fpic testPugin.c 
gcc Cprogram.c -ldl 

但是对于不确定数量的 .c 文件。

到目前为止,我已经设法查看插件目录并找到所有文件,但我坚持按照上面的第二步编译它们并输出 .so 和 .o 文件。这是我到目前为止所拥有的:

TOP := $(dir $(lastword $(CURDIR)))
PLUGDIR = $(TOP)src/plugins
PLUGSRC = $(PLUGDIR)/*.c
OBJ = $(PLUGSRC:.c=.o)
SRCS = Cprogram.c 
CFLAGS = -shared -lc
BINARY = testProg

$(BINARY): $(SRCS)
    echo $(OBJ)

但这只是输出:

⇒ make
echo /Users/fragmachine/eclipse-workspace/Cprogram/src/plugins/*.o
/Users/fragmachine/eclipse-workspace/Cprogram/src/plugins/*.o

如果我OBJ = $(PLUGSRC:.c=.o)改为OBJ = $(SRCS:.c=.o)我得到:

⇒ make
echo Cprogram.o
Cprogram.o

这是我想要的,但它只适用于一个文件。我想我一定是缺少某种通配符,但我尝试使用 % 和 * 却没有运气。

如果不清楚我要做什么,这里有一些奇怪的 make 伪代码:

$(BINARY): $(SRCS)
  gcc -shared -lc $(All plugin.c files) -o $(OBJ) #Output .o files for each plugin.c file
  gcc -shared -lc $(All plugin.c files) -o $(OBJ2) #Output .so files for each plugin.c file
  gcc -c -fpic $(All plugin.c files) # I'm not 100% sure what this does
  gcc Cprogram.c -ldl # Compile the main program

我根本没有太多经验make。我以前只做过非常简单的,所以任何帮助都将不胜感激。

4

1 回答 1

1

这里有一些让你开始的东西:

PLUGDIR = src/plugins
PLUGSRC = $(PLUGDIR)/*.c
SRCS = $(wildcard $(PLUGSRC))
OBJ = $(SRCS:.c=.o)
SOBJ = $(SRCS:.c=.so)
CFLAGS = -shared -lc
BINARY = testProg

all: $(BINARY)
    @echo "make is fun!"

$(BINARY): $(OBJ) $(SOBJ)
    @echo "build the binary $@ which depends on $^"

%.o: $(SRCS)
    @echo $@

%.so: $(SRCS)
    @echo $@

首先,这使用 $(wildcard) 函数来收集 src/plugins 目录中的所有 *.c 名称。

其次,这使用了一个依赖于所有 .o 文件和 .so 文件的目标。

第三,从 .c 文件构建 .so 和 .o 文件有两个模式规则。

第四,您的源路径使用了 $(TOP)src/plugins,但您正在构建 $(TOP),因此这不是正确的相对路径……您只需要 src/plugins。

所以当你运行它时,输出是(假设有一个名为 src/plugins/Cprogram.c 的文件):

$ make
src/plugins/Cprogram.o
src/plugins/Cprogram.so
build the binary testProg which depends on src/plugins/Cprogram.o src/plugins/Cprogram.so
make is fun!

希望从这里你应该能够弄清楚其余的。

有关更多信息,请参阅我的项目模板: https ://github.com/cdesjardins/makefiles

每当我开始一个新项目时,我都会使用该 repo 作为起点。

于 2013-03-02T09:19:15.843 回答