GHC无法识别Makefile中导入模块的问题求助
问题
开发Haskell项目时计划通过FFI用C扩展功能,编写了Makefile用Clang编译C代码、GHC编译Haskell代码,但执行make时,CalcLangInterpreter.hs无法找到已编译的CalcLangParser模块,尽管已先生成了接口文件。
Makefile内容:
#Directory Definitions SRCDIR:=./src HDIR:=$(SRCDIR)/haskell CDIR:=$(SRCDIR)/c LDIR:=./lib HLDIR:=$(LDIR)/haskell CLDIR:=$(LDIR)/c ODIR:=./obj CODIR:=$(ODIR)/c HODIR:=$(ODIR)/haskell INTDIR:=./interface/haskell INCDIR:=./include BDIR:=./bin ITARGET:=CalcLang.exe # Toolchain definitions CLANG:=clang GHC:=ghc # C compilation directives CFLAGS += -fPIC CFLAGS += -std=c99 CFLAGS += -g CFLAGS += -I$(INCDIR) # Haskell generate interface file Flags HIFLAGS += -hidir $(INTDIR) HIFLAGS += -fno-code HIFLAGS += -i$(HDIR) # Haskell compilation directives HFLAGS += -XForeignFunctionInterface HFLAGS += -fPIC HFLAGS += -flink-rts HFLAGS += -hidir $(INTDIR) #Here is a specification of the Src HISRC:=$(HDIR)/CalcLangParser.hs $(HDIR)/CalcLangInterpreter.hs $(HDIR)/CalcLangMain.hs HIINT:=$(HISRC:$(HDIR)/%.hs=$(INTDIR)/%.hi) HIOBJS:=$(HISRC:$(HDIR)/%.hs=$(HODIR)/%.o) $(INTDIR)/%.hi: $(HDIR)/%.hs $(GHC) -c $< -o $@ $(HIFLAGS) $(HODIR)/%.o: $(HDIR)/%.hs $(HIINT) $(GHC) -c $< -o $@ $(HFLAGS) $(BDIR)/$(ITARGET): $(HIOBJS) $(GHC) $^ -o $@ .PHONY: clean clean: rm -f $(HIOBJS) $(HIINT) ./*~ ./*# ./*/*/*~ ./*/*/*# $(BDIR)/*
执行make后的错误信息:
ghc -c src/haskell/CalcLangParser.hs -o interface/haskell/CalcLangParser.hi -hidir ./interface/haskell -fno-code -i./src/haskell ghc -c src/haskell/CalcLangInterpreter.hs -o interface/haskell/CalcLangInterpreter.hi -hidir ./interface/haskell -fno-code -i./src/haskell src\haskell\CalcLangInterpreter.hs:3:1: error: [GHC-87110] Could not find module `CalcLangParser'. Use -v to see a list of the files searched for. | 3 | import CalcLangParser
解决方案
问题核心是GHC在生成接口文件和编译目标文件时,找不到依赖模块的接口路径,同时模块间的依赖关系未明确声明。
1. 补充接口文件搜索路径
生成接口文件的HIFLAGS仅指定了源码目录,未包含接口文件所在的INTDIR,导致编译CalcLangInterpreter.hi时找不到已生成的CalcLangParser.hi。修改HIFLAGS:
# Haskell generate interface file Flags HIFLAGS += -hidir $(INTDIR) HIFLAGS += -fno-code HIFLAGS += -i$(HDIR) HIFLAGS += -i$(INTDIR) # 添加接口文件搜索路径
同时,编译目标文件的HFLAGS也需要补充这两个路径,否则后续编译.o文件时同样会找不到模块:
# Haskell compilation directives HFLAGS += -XForeignFunctionInterface HFLAGS += -fPIC HFLAGS += -flink-rts HFLAGS += -hidir $(INTDIR) HFLAGS += -i$(HDIR) # 添加源码搜索路径 HFLAGS += -i$(INTDIR) # 添加接口文件搜索路径
2. 明确模块依赖关系
原Makefile中,.hi文件的生成规则仅依赖对应的.hs文件,未声明模块间的依赖,可能导致make并行编译时顺序错误。手动添加依赖规则:
# 声明模块间的依赖关系 $(INTDIR)/CalcLangInterpreter.hi: $(HDIR)/CalcLangInterpreter.hs $(INTDIR)/CalcLangParser.hi $(INTDIR)/CalcLangMain.hi: $(HDIR)/CalcLangMain.hs $(INTDIR)/CalcLangParser.hi $(INTDIR)/CalcLangInterpreter.hi
完成上述修改后重新执行make,即可正确解析模块依赖。
内容的提问来源于stack exchange,提问作者Jacob Bauer
相关产品推荐
相关产品推荐

