链接 LLVM IR 库
Linking LLVM IR Libraries
我正在关注 LLVM Kaleidoscope Tutorial (Ch. 3),并且在尝试 link LLVM IR 库后遇到错误(毫无疑问来自我的 Makefile)。我的 Makefile 和项目结构:
CPP=clang++
CFLAGS=-g -Wall -std=c++14
LDFLAGS:=$(shell llvm-config --cxxflags --ldflags --system-libs --libs core)
EXEC=comp.out
SRCS:=$(shell find src -type f -name '*.cpp')
OBJS:=$(patsubst %.cpp,%.o,$(SRCS))
all: $(EXEC)
$(EXEC): $(OBJS)
$(CPP) $(CFLAGS) -o $@ $^
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $<
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $<
.PHONY: clean
clean:
rm -f $(shell find src -type f -name '*.o')
rm -f $(EXEC)
.
└── src
├── main.cpp
├── [.cpp files]
│
├── ast
│ ├── [.cpp files]
│ │
│ └── include
│ └── [.h files]
│
└── include
└── [.h files]
制作时出现错误:
clang++ -g -Wall -std=c++14 -I/usr/local/Cellar/llvm/12.0.1/include -std=c++14 -stdlib=libc++ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/local/Cellar/llvm/12.0.1/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-12 src/IMRep.cpp -o src/IMRep.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:19: src/IMRep.o] Error 1
从上面的错误来看,main.cpp
在编译错误出现之前从未编译过。它只到达 src/IMRep.cpp
文件(不确定这是否重要)。如果我添加 -c
标志使其成为:
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $@
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $@
尽管有大量警告消息说 linker inputs/arguments 未使用,但我能够成功 运行 程序。这些警告是预料之中的,因为 -c
只编译而不 link.
在main.cpp
中:
#include <iostream>
int main(int argc, char *argv[])
{
return 0;
}
所以这个问题不会被标记为骗局:
: main.cpp
包含在 OBJS
中
[2]:添加了 -c
标志并收到许多关于未使用 linker arguments/input 的警告(因为 -c
用于编译,而不是 linkage)
:我只在有一个依赖的地方使用$<
,在有多个
的地方使用$^
: 无法应用此问题的答案
[5]: SRCS
和 OBJS
中的所有文件都是正确的文件。我通过制定 'verbose' 规则并打印这些值和 make verbose
来验证这一点
这让我相信我没有正确地link使用这些库。
事实上,您的问题与那里的 #2 答案重复。
当您想要创建目标文件时,您必须 使用-c
选项。这就是 -c
选项的意思。
如果您不想要“大量警告消息说链接器 inputs/arguments 未使用”,那么,您知道的,不要添加链接器输入和参数 当你生成目标文件时!这些参数用于链接,而不是编译。
您的 .o
规则应该是:
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) -c $< -o $@
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) -c $< -o $@
只是指出您不需要上述两种模式规则。如果您希望目标文件与源文件位于同一目录中,您可以这样写:
%.o: %.cpp
$(CPP) $(CFLAGS) -c $< -o $@
而且,如果您改用标准 make 变量而不是使用非标准变量:
# CPP is the C preprocessor, not C++
CXX = clang++
# CFLAGS is flags for the C compiler, not C++
CXXFLAGS := -g -Wall -std=c++14 $(shell llvm-config --cxxflags core)
LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core)
那么你根本不需要定义自己的模式规则,因为 make 有一个内置规则,它知道如何将 C++ 源文件编译成目标文件。
我正在关注 LLVM Kaleidoscope Tutorial (Ch. 3),并且在尝试 link LLVM IR 库后遇到错误(毫无疑问来自我的 Makefile)。我的 Makefile 和项目结构:
CPP=clang++
CFLAGS=-g -Wall -std=c++14
LDFLAGS:=$(shell llvm-config --cxxflags --ldflags --system-libs --libs core)
EXEC=comp.out
SRCS:=$(shell find src -type f -name '*.cpp')
OBJS:=$(patsubst %.cpp,%.o,$(SRCS))
all: $(EXEC)
$(EXEC): $(OBJS)
$(CPP) $(CFLAGS) -o $@ $^
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $<
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $<
.PHONY: clean
clean:
rm -f $(shell find src -type f -name '*.o')
rm -f $(EXEC)
.
└── src
├── main.cpp
├── [.cpp files]
│
├── ast
│ ├── [.cpp files]
│ │
│ └── include
│ └── [.h files]
│
└── include
└── [.h files]
制作时出现错误:
clang++ -g -Wall -std=c++14 -I/usr/local/Cellar/llvm/12.0.1/include -std=c++14 -stdlib=libc++ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/local/Cellar/llvm/12.0.1/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-12 src/IMRep.cpp -o src/IMRep.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:19: src/IMRep.o] Error 1
从上面的错误来看,main.cpp
在编译错误出现之前从未编译过。它只到达 src/IMRep.cpp
文件(不确定这是否重要)。如果我添加 -c
标志使其成为:
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $@
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $@
尽管有大量警告消息说 linker inputs/arguments 未使用,但我能够成功 运行 程序。这些警告是预料之中的,因为 -c
只编译而不 link.
在main.cpp
中:
#include <iostream>
int main(int argc, char *argv[])
{
return 0;
}
所以这个问题不会被标记为骗局:
main.cpp
包含在 OBJS
中
[2]:添加了 -c
标志并收到许多关于未使用 linker arguments/input 的警告(因为 -c
用于编译,而不是 linkage)
$<
,在有多个
的地方使用$^
[5]: SRCS
和 OBJS
中的所有文件都是正确的文件。我通过制定 'verbose' 规则并打印这些值和 make verbose
这让我相信我没有正确地link使用这些库。
事实上,您的问题与那里的 #2 答案重复。
当您想要创建目标文件时,您必须 使用-c
选项。这就是 -c
选项的意思。
如果您不想要“大量警告消息说链接器 inputs/arguments 未使用”,那么,您知道的,不要添加链接器输入和参数 当你生成目标文件时!这些参数用于链接,而不是编译。
您的 .o
规则应该是:
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) -c $< -o $@
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) -c $< -o $@
只是指出您不需要上述两种模式规则。如果您希望目标文件与源文件位于同一目录中,您可以这样写:
%.o: %.cpp
$(CPP) $(CFLAGS) -c $< -o $@
而且,如果您改用标准 make 变量而不是使用非标准变量:
# CPP is the C preprocessor, not C++
CXX = clang++
# CFLAGS is flags for the C compiler, not C++
CXXFLAGS := -g -Wall -std=c++14 $(shell llvm-config --cxxflags core)
LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core)
那么你根本不需要定义自己的模式规则,因为 make 有一个内置规则,它知道如何将 C++ 源文件编译成目标文件。