我正在做一个首次使用pocketspinx的项目,在编译我的程序时遇到了很多麻烦。自从尼古拉帮我找出问题所在以来,我对这个问题进行了一些编辑,但是我仍然无法让我的程序编译。
我试图将pocketspinx文档中的编译标志分割开来,使它们成为友好的Makefile,但我一定是把它们放错了位置。我得到了错误:

src/server/server.c:41:20: error: use of undeclared identifier 'MODELDIR'
                         "-hmm", MODELDIR "/en-us/en-us",
                                 ^
1 error generated.

我会共享我的server.c,但是错误消息告诉我错误不在我的文件中——一定是某些东西链接不正确,因为我应该能够使用MODELDIR
在这一点上,我猜我把-DMODELDIR=\"$(MODELDIR)\"放错了地方。我一直在google上搜索,但找不到任何解释在哪里放置-DMODELDIR=\"$(MODELDIR)\"
这就是我在Makefile中声明MODELDIR变量的方式:
MODELDIR = $(shell pkg-config --variable=modeldir pocketsphinx)
这就是我用来编译的地方:
$(NAME_SV): $(OBJ_SV) $(OBJ_HL) $(OBJ_CM)
    @echo "\033[32mCompiling $(NAME_SV)...\033[0m"
    @gcc $(OBJ_SV) $(OBJ_HL) $(OBJ_CM) $(LINK) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_LIBS) -lm -o $(NAME_SV)
    @echo "\033[1;4;32m[\xE2\x9C\x94] $(NAME_SV) Created.\033[0m\n"

对于透视图,这里是我的整个Makefile:
NAME_CL = client
NAME_SV = server
CFLAGS = -Wall -Werror -Wextra -g
MODELDIR = $(shell pkg-config --variable=modeldir pocketsphinx)
SPHX_FLAGS = $(shell pkg-config --cflags pocketsphinx sphinxbase)
SPHX_LIBS = $(shell pkg-config --libs pocketsphinx sphinxbase)

# SV - Server specific files
# CL - Client specific files
# HL - Files containing helper functions used in both client and server
# CM - Files with commands to be executed by server

SRC_SV = server.c
SRC_CL = client.c
SRC_HL = network_helpers.c
SRC_CM = example.c

OBJ_CL_FILES = $(SRC_CL:.c=.o)
OBJ_SV_FILES = $(SRC_SV:.c=.o)
OBJ_HL_FILES = $(SRC_HL:.c=.o)
OBJ_CM_FILES = $(SRC_CM:.c=.o)

HL_DIR = ./src/helpers/
CL_DIR = ./src/client/
SV_DIR = ./src/server/
CM_DIR = ./src/server/cmds/
OBJ_DIR = ./obj/
OBJ_CL_DIR = ./obj/client/
OBJ_CM_DIR = ./obj/server/
OBJ_SV_DIR = ./obj/server/
OBJ_HL_DIR = ./obj/helpers/
INC_DIR = ./include/
LIBFT_DIR = ./libft/
SPHX_DIR = ./cmusphinx/

OBJ_CL = $(addprefix $(OBJ_CL_DIR), $(OBJ_CL_FILES))
OBJ_SV = $(addprefix $(OBJ_SV_DIR), $(OBJ_SV_FILES))
OBJ_HL = $(addprefix $(OBJ_HL_DIR), $(OBJ_HL_FILES))
OBJ_CM = $(addprefix $(OBJ_SV_DIR), $(OBJ_CM_FILES))
LIBFT = $(addprefix $(LIBFT_DIR), libft.a)

LINK = -L $(LIBFT_DIR) -lft $(SPHX_LIBS)

all: obj $(LIBFT) $(NAME_CL) $(NAME_SV)

obj:
    @mkdir -p $(OBJ_CL_DIR)
    @mkdir -p $(OBJ_SV_DIR)
    @mkdir -p $(OBJ_HL_DIR)

$(OBJ_CL_DIR)%.o:$(CL_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_SV_DIR)%.o:$(SV_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_HL_DIR)%.o:$(HL_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_CM_DIR)%.o:$(CM_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) $(SPHX_FLAGS) -o $@ -c $<

$(LIBFT):
    @echo "\033[32mCompiling libft...\033[0m"
    @make -C $(LIBFT_DIR)
    @echo "\033[1;4;32m[\xE2\x9C\x94] libft created.\033[0m\n"

$(NAME_CL): $(OBJ_CL) $(OBJ_HL)
    @echo "\033[32mCompiling $(NAME_CL)...\033[0m"
    @gcc $(OBJ_HL) $(OBJ_CL) $(LINK) -lm -o $(NAME_CL)
    @echo "\033[1;4;32m[\xE2\x9C\x94] $(NAME_CL) Created.\033[0m\n"

$(NAME_SV): $(OBJ_SV) $(OBJ_HL) $(OBJ_CM)
    @echo "\033[32mCompiling $(NAME_SV)...\033[0m"
    @gcc $(OBJ_SV) $(OBJ_HL) $(OBJ_CM) $(LINK) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_LIBS) -lm -o $(NAME_SV)
    @echo "\033[1;4;32m[\xE2\x9C\x94] $(NAME_SV) Created.\033[0m\n"

clean:
    @echo "\033[31mRemoving source objects...\033[0m"
    @rm -rf $(OBJ_DIR)
    @echo "\033[4;31m[\xE2\x9D\x8C ] Source objects removed!\033[0m\n"
    @echo "\033[31mRemoving libft objects...\033[0m"
    @make -C $(LIBFT_DIR) clean
    @echo "\033[4;31m[\xE2\x9D\x8C ] libft Objects removed!\033[0m\n"
    @echo "\033[1;4;91m-----All objects removed!-----\033[0m\n"

clean_client:
    @echo "\033[31mRemoving client objects...\033[0m"
    @rm -rf $(OBJ_CL_DIR)
    @rm -rf $(OBJ_HL_DIR)
    @make -C $(LIBFT_DIR) clean
    @echo "\033[4;31m[\xE2\x9D\x8C ] Client objects removed!\033[0m"

clean_server:
    @echo "\033[31mRemoving server objects...\033[0m"
    @rm -rf $(OBJ_SV_DIR)
    @rm -rf $(OBJ_HL_DIR)
    @make -C $(LIBFT_DIR) clean
    @echo "\033[4;31m[\xE2\x9D\x8C ] Server objects removed!\033[0m"

fclean: clean
    @echo "\033[31mRemoving $(NAME_CL)...\033[0m"
    @rm -f $(NAME_CL)
    @echo "\033[4;31m[\xE2\x9D\x8C ] $(NAME_CL) removed!\033[0m\n"
    @echo "\033[31mRemoving $(NAME_SV)...\033[0m"
    @rm -f $(NAME_SV)
    @echo "\033[4;31m[\xE2\x9D\x8C ] $(NAME_SV) removed!\033[0m\n"
    @echo "\033[31mRemoving libft objects and libft.a...\033[0m"
    @make -C $(LIBFT_DIR) fclean
    @echo "\033[4;31m[\xE2\x9D\x8C ] libft objects and libft.a removed!!\033[0m\n"
    @echo "\033[1;4;31m-----All objects, executables and lib files removed!-----\033[0m\n"

re: fclean all

.PHONY: clean clean_client clean_server fclean all re

最佳答案

经过几个小时的实验,我终于找到了编译程序的正确方法。非常感谢尼古拉,因为没有他的帮助我是无法解决这个问题的。我想我会在这里发布我的解决方案,以防其他人遇到同样的问题,因为我发现很难找到任何关于如何使用Makefile编译的资源——这些文档告诉您如何使用终端编译,但是正如尼古拉所说,当您使用Makefile时,必须以不同的方式编译。
这就是我如何分割编译参数的方法

MODELDIR = $(shell pkg-config --variable=modeldir pocketsphinx)
SPHX_FLAGS = $(shell pkg-config --cflags pocketsphinx sphinxbase)
SPHX_LIBS = $(shell pkg-config --libs pocketsphinx sphinxbase)

# Variable for linking
LINK = -L $(LIBFT_DIR) -lft $(SPHX_LIBS)

我就是这样整理的:
#Compiling source to objects here
$(OBJ_CL_DIR)%.o:$(CL_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_SV_DIR)%.o:$(SV_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_HL_DIR)%.o:$(HL_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_CM_DIR)%.o:$(CM_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

# Compiling objects to executable here
$(NAME_SV): $(OBJ_SV) $(OBJ_HL) $(OBJ_CM)
    @echo "\033[32mCompiling $(NAME_SV)...\033[0m"
    @gcc $(OBJ_SV) $(OBJ_HL) $(OBJ_CM) $(LINK) $(SPHX_LIBS) -lm -o $(NAME_SV)
    @echo "\033[1;4;32m[\xE2\x9C\x94] $(NAME_SV) Created.\033[0m\n"

请在此填写Makefile以供参考:
NAME_CL = client
NAME_SV = server
CFLAGS = -Wall -Werror -Wextra -g
MODELDIR = $(shell pkg-config --variable=modeldir pocketsphinx)
SPHX_FLAGS = $(shell pkg-config --cflags pocketsphinx sphinxbase)
SPHX_LIBS = $(shell pkg-config --libs pocketsphinx sphinxbase)

# SV - Server specific files
# CL - Client specific files
# HL - Files containing helper functions used in both client and server
# CM - Files with commands to be executed by server

SRC_SV = server.c
SRC_CL = client.c
SRC_HL = network_helpers.c
SRC_CM = example.c

OBJ_CL_FILES = $(SRC_CL:.c=.o)
OBJ_SV_FILES = $(SRC_SV:.c=.o)
OBJ_HL_FILES = $(SRC_HL:.c=.o)
OBJ_CM_FILES = $(SRC_CM:.c=.o)

HL_DIR = ./src/helpers/
CL_DIR = ./src/client/
SV_DIR = ./src/server/
CM_DIR = ./src/server/cmds/
OBJ_DIR = ./obj/
OBJ_CL_DIR = ./obj/client/
OBJ_CM_DIR = ./obj/server/
OBJ_SV_DIR = ./obj/server/
OBJ_HL_DIR = ./obj/helpers/
INC_DIR = ./include/
LIBFT_DIR = ./libft/
SPHX_DIR = ./cmusphinx/

OBJ_CL = $(addprefix $(OBJ_CL_DIR), $(OBJ_CL_FILES))
OBJ_SV = $(addprefix $(OBJ_SV_DIR), $(OBJ_SV_FILES))
OBJ_HL = $(addprefix $(OBJ_HL_DIR), $(OBJ_HL_FILES))
OBJ_CM = $(addprefix $(OBJ_SV_DIR), $(OBJ_CM_FILES))
LIBFT = $(addprefix $(LIBFT_DIR), libft.a)

LINK = -L $(LIBFT_DIR) -lft $(SPHX_LIBS)

all: obj $(LIBFT) $(NAME_CL) $(NAME_SV)

obj:
    @mkdir -p $(OBJ_CL_DIR)
    @mkdir -p $(OBJ_SV_DIR)
    @mkdir -p $(OBJ_HL_DIR)

$(OBJ_CL_DIR)%.o:$(CL_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_SV_DIR)%.o:$(SV_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_HL_DIR)%.o:$(HL_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(OBJ_CM_DIR)%.o:$(CM_DIR)%.c
    @gcc -I $(LIBFT_DIR) -I $(INC_DIR) -DMODELDIR=\"$(MODELDIR)\" $(SPHX_FLAGS) -o $@ -c $<

$(LIBFT):
    @echo "\033[32mCompiling libft...\033[0m"
    @make -C $(LIBFT_DIR)
    @echo "\033[1;4;32m[\xE2\x9C\x94] libft created.\033[0m\n"

$(NAME_CL): $(OBJ_CL) $(OBJ_HL)
    @echo "\033[32mCompiling $(NAME_CL)...\033[0m"
    @gcc $(OBJ_HL) $(OBJ_CL) $(LINK) -lm -o $(NAME_CL)
    @echo "\033[1;4;32m[\xE2\x9C\x94] $(NAME_CL) Created.\033[0m\n"

$(NAME_SV): $(OBJ_SV) $(OBJ_HL) $(OBJ_CM)
    @echo "\033[32mCompiling $(NAME_SV)...\033[0m"
    @gcc $(OBJ_SV) $(OBJ_HL) $(OBJ_CM) $(LINK) $(SPHX_LIBS) -lm -o $(NAME_SV)
    @echo "\033[1;4;32m[\xE2\x9C\x94] $(NAME_SV) Created.\033[0m\n"

clean:
    @echo "\033[31mRemoving source objects...\033[0m"
    @rm -rf $(OBJ_DIR)
    @echo "\033[4;31m[\xE2\x9D\x8C ] Source objects removed!\033[0m\n"
    @echo "\033[31mRemoving libft objects...\033[0m"
    @make -C $(LIBFT_DIR) clean
    @echo "\033[4;31m[\xE2\x9D\x8C ] libft Objects removed!\033[0m\n"
    @echo "\033[1;4;91m-----All objects removed!-----\033[0m\n"

clean_client:
    @echo "\033[31mRemoving client objects...\033[0m"
    @rm -rf $(OBJ_CL_DIR)
    @rm -rf $(OBJ_HL_DIR)
    @make -C $(LIBFT_DIR) clean
    @echo "\033[4;31m[\xE2\x9D\x8C ] Client objects removed!\033[0m"

clean_server:
    @echo "\033[31mRemoving server objects...\033[0m"
    @rm -rf $(OBJ_SV_DIR)
    @rm -rf $(OBJ_HL_DIR)
    @make -C $(LIBFT_DIR) clean
    @echo "\033[4;31m[\xE2\x9D\x8C ] Server objects removed!\033[0m"

fclean: clean
    @echo "\033[31mRemoving $(NAME_CL)...\033[0m"
    @rm -f $(NAME_CL)
    @echo "\033[4;31m[\xE2\x9D\x8C ] $(NAME_CL) removed!\033[0m\n"
    @echo "\033[31mRemoving $(NAME_SV)...\033[0m"
    @rm -f $(NAME_SV)
    @echo "\033[4;31m[\xE2\x9D\x8C ] $(NAME_SV) removed!\033[0m\n"
    @echo "\033[31mRemoving libft objects and libft.a...\033[0m"
    @make -C $(LIBFT_DIR) fclean
    @echo "\033[4;31m[\xE2\x9D\x8C ] libft objects and libft.a removed!!\033[0m\n"
    @echo "\033[1;4;31m-----All objects, executables and lib files removed!-----\033[0m\n"

re: fclean all

.PHONY: clean clean_client clean_server fclean all re

10-07 23:09