我正在尝试在Trivia服务器程序中使用mongo C驱动程序,用它来跟踪登录信息分数等。
我花了相当多的时间来弄清楚如何在makefile中编译东西但是我能够包含mongoc.h所以像mongoc_client这样的东西工作得很好。一旦我尝试实际使用一个函数,例如mongoc_init我得到
> undefined reference to `mongoc_init'
我觉得事情应该链接,因为mongoc.h包含所有其他头文件,看起来它正确链接。这是我的makefile - 我不知道该怎么做,甚至不知道提供什么信息来解决这个问题。
client:
make -f makefile.client
server:
make -f makefile.server
clean:
rm -f *~ *.o tserve core tclient core *.tar *.zip *.gzip *.bzip *.gz
^ Makefile
C = gcc
CFLAGS = -g -Wall
LDFLAGS = -lpthread
INFO = -L/usr/local/lib -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -lmongoc-1.0 -lbson-1.0
all: tserve
csapp.o: csapp.c csapp.h
$(CC) $(CFLAGS) -c csapp.c
tserve.o: tserve.c readq.h csapp.h
$(CC) $(CFLAGS) -c tserve.c $(INFO)
readq.o: readq.c readq.h csapp.h
$(CC) $(CFLAGS) -c readq.c
tserve: tserve.o readq.o csapp.o
^ makefile.server
C = gcc
CFLAGS = -g -Wall
LDFLAGS = -lpthread
all: tclient
csapp.o: csapp.c csapp.h
$(CC) $(CFLAGS) -c csapp.c
tclient.o: tclient.c csapp.h
$(CC) $(CFLAGS) -c tclient.c
tclient: tclient.o csapp.o
^ makefile.client
如果值得注意 - 系统问题是使用以下代码安装了驱动程序
system("wget https://github.com/mongodb/mongo-c-driver/releases/download/1.0.2/mongo-c-driver-1.0.2.tar.gz");
system("tar -xzf mongo-c-driver-1.0.2.tar.gz");
system("rm mongo-c-driver-1.0.2.tar.gz");
if (chdir("mongo-c-driver-1.0.2"))
perror("error:");
system("./configure --prefix=/usr --libdir=/usr/lib64");
system("make");
system("sudo make install");
答案 0 :(得分:0)
您只能使用包含INFO
的{{1}}变量(这是您需要的)来构建-lmongoc-1.0 -lbson-1.0
。在此构建步骤中,不涉及链接器,因此不评估tserve.o
选项并且不执行任何操作。相反,您需要在构建-l
时指定它们。
您可以通过提供执行此操作的tserve
的配方来解决此问题,例如
tserve
...但在我看来,将tserve: tserve.o readq.o csapp.o
$(CC) $(LDFLAGS) $(INFO) -o $@ $+
拆分并将部分放入预定义规则用于相关目的的变量会更好。然后你的整个Makefile可以替换为
INFO
然后将通过隐式规则构建# C compiler
CC = gcc
# C compiler flags
CFLAGS = -g -Wall
# C preprocessor flags
CPPFLAGS = -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -pthread
# Linker flags
LDFLAGS = -L/usr/local/lib -pthread
# Libraries
LDLIBS = -lmongoc-1.0 -lbson-1.0
all: tserve
csapp.o: csapp.c csapp.h
tserve.o: tserve.c readq.h csapp.h
readq.o: readq.c readq.h csapp.h
tserve: tserve.o readq.o csapp.o
文件,这些规则从相应的.o
文件生成它们并使用.c
和CPPFLAGS
,从而省去了指定配方的麻烦显式 - 仅存在跟踪依赖关系的规则 - 链接步骤使用使用CFLAGS
和LDFLAGS
的隐式规则。请注意,我在LDLIBS
和-pthread
中都提供了CPPFLAGS
,因为它与预处理器和链接器都相关。
有关详细信息,请参阅GNU制作手册中有关implicit rules的内容,并谈到依赖关系跟踪,您可能会发现this article关于自动化它的启发。
答案 1 :(得分:0)
the following file is expected to be named Makefile.mak
# note: with very minor changes this should work for most C projects
# irregardless of the OS being used
SHELL := /bin/sh
.PHONY: all clean
#
# macro for all *.c files
# (NOTE:
# (the following 'wildcard' will pick up ALL .c files
# (like FileHeader.c and FunctionHeader.c
# (which should not be part of the build
# (so be sure no unwanted .c files in directory
# (or change the extension
#
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)
CC := /usr/bin/gcc
MAKE := /usr/bin/make
name := tserve
CFLAGS := -c -g -std=c11 -Wall -Wextra -pedantic-errors
#CPPFLAGS += =MD
# when #(DEBUG) is used in the compile/link steps,
# them max info for the gdb debugger is generated
DEBUG := -ggdb3
LDFLAGS := -L/lib -L/usr/lib -L/usr/local/lib
LIBS := -lpthread -lmongoc-1.0 -lbson-1.0
INC := -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0
name := tserve
all: $(name)
#
# link the .o files into the executable
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ)
#
# ======= $(name) Link Start =========
$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
# ======= $(name) Link Done ==========
#
#
#create dependancy files
# -- inference rule
#
%.d: %.c Makefile.mak
#
# ========= START $< TO $@ =========
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# ========= END $< TO $@ =========
#
# compile the .c file into .o files using the compiler flags
# -- inference rule
#
%.o: %.c %.d
#
# ========= START $< TO $@ =========
$(CC) $(CCFLAGS) -c $< -o $@ -I. $(INC)
# ========= END $< TO $@ =========
#
clean:
# ========== CLEANING UP ==========
rm -f *.o
rm -f $(name).map
rm -f $(name)
rm -f *.d
# ========== DONE ==========
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEP)
endif