Pocketsphinx - 使用Makefile链接/包含库的正确方法是什么?

时间:2017-10-14 05:25:40

标签: c makefile path cmusphinx pocketsphinx

我正在开发一个第一次使用pocketsphinx的项目,我在编译程序时遇到了很多麻烦。我已经编辑了这个问题,因为Nikolay帮助我确定了我的问题所在,但是我仍然无法编译我的程序。

我试图从pocketsphinx文档中拆分编译标志,使它们对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 < / p>

此时我猜我把-DMODELDIR=\"$(MODELDIR)\"放在了错误的地方。我一直在谷歌上搜索,我找不到任何可以解释放在哪里的内容-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

1 个答案:

答案 0 :(得分:1)

经过几个小时的实验,我终于想出了编写程序的正确方法。非常感谢尼古拉,因为没有他的帮助我无法解决这个问题。我想我会在这里发布我的解决方案,只是因为其他人最终遇到同样的问题,因为我发现很难找到有关如何用Makefile编译的任何资源 - 文档告诉你如何用终端编译,但正如Nikolay所说,当你使用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