使用 clang++ 使用 SCons 编译 Antlr4 cpp 运行时。结果库给了我未定义的符号(macos)
Compiling Antlr4 cpp runtime with SCons using clang++. Resulting library gives me undefined symbols (macos)
我正在尝试制作一个 SConstruct,它将...
- 将Antlr4 cpp runtime构建为静态库
- 使用 Antrl4(java 应用程序)以 cpp 格式构建 Lexer、Parser、Visitor 和 Listener,以获得简单的语法。
- 构建一个简单的程序来解析具有该语法的文件
全部在 Macos (Catalina) 上使用 Clang++
现在我不得不说我不是 C++ 专家,所以我可能遗漏了一些非常明显的东西......希望如此。
我遇到的问题是第一步和最后一步。
我可以构建 Antlr4 运行时,但稍后它不会 link 与最终程序。简单地调用 #include "antlr4-runtime.h"
会导致 Undefined symbols for architecture x86_64
错误。
奇怪的是,如果我使用 cmake 构建 Antlr4 运行时,如 Antlr 存储库中所述,那么 linking 问题就会消失。
所以我用 cmake 构建它并使用 VERBOSE 模式查看 make 如何构建各种目标文件并确保我使用与 Scons 相同的标志
cmake/make 的输出示例:
clang++
-Iantlr4-master/runtime/Cpp/runtime/src
-Iantlr4-master/runtime/Cpp/runtime/src/atn
-Iantlr4-master/runtime/Cpp/runtime/src/dfa
-Iantlr4-master/runtime/Cpp/runtime/src/misc
-Iantlr4-master/runtime/Cpp/runtime/src/support
-Iantlr4-master/runtime/Cpp/runtime/src/tree
-Iantlr4-master/runtime/Cpp/runtime/src/tree/pattern
-Iantlr4-master/runtime/Cpp/runtime/src/tree/xpath
-Wall -pedantic -W -std=c++11 -stdlib=libc++ -O3 -DNDEBUG -O3 -DNDEBUG
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants -std=gnu++11
-o CMakeFiles/antlr4_static.dir/src/atn/PredicateTransition.cpp.o
-c antlr4-master/runtime/Cpp/runtime/src/atn/PredicateTransition.cpp
显然这应该是一行,但为了更容易阅读,我分成了多行 ;)
所以我抓取了所有这些标志并将它们放入一个字符串中,让 Scons 弄清楚如何将它们应用到环境中:
pf = env.ParseFlags('\
-Wall -pedantic -W -O3 -std=c++11 -stdlib=libc++ -DNDEBUG -std=gnu++11 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk \
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants')
env.MergeFlags(pf)
现在我用 SCons 再次构建了 Antlr4,这是 SCons 创建的命令示例:
clang++
-o antlr4-master/runtime/Cpp/runtime/src/atn/PredicateTransition.o
-c
-std=c++11 -stdlib=libc++ -Wall -pedantic -W -O3
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants -DNDEBUG
-Iantlr4-master/runtime/Cpp/runtime/src
antlr4-master/runtime/Cpp/runtime/src/atn/PredicateTransition.cpp
我再次分成多行只是为了便于阅读...
我注意到的第一件事是命令中参数的顺序在 SCons 中无处不在,但其余部分几乎相同。
不幸的是,这给了我同样的 Undefined symbols for architecture x86_64
错误。
可能你注意到我只包含了 antlr4 运行时的主目录,这应该可以工作,因为所有的包含都从那个目录开始......无论如何,我也尝试像 cmake/make 那样包含所有子文件夹,结果是一样的。
我现在真的是一头雾水。希望你们中的一些人能够为我指明正确的方向。
这是我的 SConstruct 文件(路径与示例不同。但应该无关紧要)
import os
import subprocess
env = Environment(
CC = "clang",
CXX = "clang++",
CXXFLAGS = ['-std=c++11', '-stdlib=libc++'],
LINKFLAGS = ['-stdlib=libc++'],
)
env.Append(ENV = {'CLASSPATH': './dependencies/antlr4/antlr-4.8-complete.jar'})
#
# Builder for generating grammar files with antlr4 (the java app)
#
def antlr_emitter(target, source, env):
root = os.path.splitext(source[0].name)[0]
target = ['./src/Parser/{}{}.cpp'.format(root, p) for p in (
'BaseListener',
'BaseVisitor',
'Lexer',
'Listener',
'Parser',
'Visitor'
)]
return target, source
AntlrBuilder = Builder(
action='java org.antlr.v4.Tool $SOURCE -Dlanguage=Cpp -package Coral -visitor -listener -o src/Parser',
emitter=antlr_emitter
)
env.Append(BUILDERS={'Antlr': AntlrBuilder})
#
# Cloning the Environment for Antlr4 runtime
#
antlrEnv = env.Clone()
pf = antlrEnv.ParseFlags('\
-Wall -pedantic -W -O3 -DNDEBUG -std=gnu++11 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk \
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants')
antlrEnv.MergeFlags(pf)
#
# Building in 3 steps, first the antlr4 runtime library, then the parser files with Antlr then the final program
#
AntlrRuntime = antlrEnv.Library(
'antlr4-runtime',
source =
Glob('./dependencies/antlr4Runtime/*.cpp') + \
Glob('./dependencies/antlr4Runtime/atn/*.cpp') + \
Glob('./dependencies/antlr4Runtime/dfa/*.cpp') + \
Glob('./dependencies/antlr4Runtime/misc/*.cpp') + \
Glob('./dependencies/antlr4Runtime/support/.cpp') + \
Glob('./dependencies/antlr4Runtime/tree/*.cpp') + \
Glob('./dependencies/antlr4Runtime/tree/pattern/*.cpp') + \
Glob('./dependencies/antlr4Runtime/tree/xpath/*.cpp'),
CPPPATH = './dependencies/antlr4Runtime',
ARFLAGS = 'qc'
)
ParserFiles = env.Antlr(source='Coral.g4')
CoralLang = env.Program(target = 'coral',
source = Glob('./src/*.cpp') + Glob('./src/Parser/*.cpp'),
CPPPATH = ['./src', './dependencies/antlr4Runtime'],
LIBPATH = '.',
LIBS = 'antlr4-runtime'
)
Requires(ParserFiles, AntlrRuntime)
Depends(CoralLang, ParserFiles)
Clean(ParserFiles, Glob('./src/Parser/*'))
最后是 main.cpp 文件。如您所见,它什么都没有,只是对 antlr 运行时的包含,这足以看到错误。
#include <cstdio>
#include "antlr4-runtime.h"
int main(int argc, const char *argv[])
{
if (!argv[1]) {
printf("hey! pass at least a file to parse...");
return 0;
}
else {
printf("parsing %s\n", argv[1]);
}
return 1;
}
尝试构建具有相对错误的程序时,整个 SCons 的输出是这样的:
clang++ -o src/Parser/CoralParser.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralParser.cpp
clang++ -o src/Parser/CoralBaseVisitor.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralBaseVisitor.cpp
clang++ -o src/Parser/CoralListener.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralListener.cpp
clang++ -o src/Parser/CoralVisitor.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralVisitor.cpp
clang++ -o src/Parser/CoralBaseListener.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralBaseListener.cpp
clang++ -o src/Parser/CoralLexer.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralLexer.cpp
clang++ -o coral -stdlib=libc++ src/main.o src/Parser/CoralBaseListener.o src/Parser/CoralBaseVisitor.o src/Parser/CoralLexer.o src/Parser/CoralListener.o src/Parser/CoralParser.o src/Parser/CoralVisitor.o -L. -lantlr4-runtime
Undefined symbols for architecture x86_64:
"Guid::Guid(unsigned short const*, bool)", referenced from:
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::toUUID(unsigned short const*, unsigned long) in libantlr4-runtime.a(ATNDeserializer.o)
"Guid::Guid(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
antlr4::atn::ATNDeserializer::ADDED_PRECEDENCE_TRANSITIONS() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::ADDED_LEXER_ACTIONS() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::ADDED_UNICODE_SMP() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::SERIALIZED_UUID() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::BASE_SERIALIZED_UUID() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::SUPPORTED_UUIDS() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
...
"Guid::Guid(Guid const&)", referenced from:
antlr4::atn::ATNDeserializer::SUPPORTED_UUIDS() in libantlr4-runtime.a(ATNDeserializer.o)
"antlr4::ANTLRErrorListener::~ANTLRErrorListener()", referenced from:
antlr4::Recognizer::Recognizer() in libantlr4-runtime.a(Recognizer.o)
antlr4::Recognizer::~Recognizer() in libantlr4-runtime.a(Recognizer.o)
antlr4::ProxyErrorListener::~ProxyErrorListener() in libantlr4-runtime.a(ProxyErrorListener.o)
antlr4::ProxyErrorListener::~ProxyErrorListener() in libantlr4-runtime.a(ProxyErrorListener.o)
antlr4::ConsoleErrorListener::~ConsoleErrorListener() in libantlr4-runtime.a(ConsoleErrorListener.o)
antlr4::ConsoleErrorListener::~ConsoleErrorListener() in libantlr4-runtime.a(ConsoleErrorListener.o)
antlr4::BaseErrorListener::~BaseErrorListener() in libantlr4-runtime.a(BaseErrorListener.o)
...
"antlrcpp::replaceAll(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
antlr4::Recognizer::getTokenErrorDisplay(antlr4::Token*) in libantlr4-runtime.a(Recognizer.o)
antlr4::DefaultErrorStrategy::escapeWSAndQuote(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const in libantlr4-runtime.a(DefaultErrorStrategy.o)
antlr4::CommonToken::toString(antlr4::Recognizer*) const in libantlr4-runtime.a(CommonToken.o)
"antlrcpp::arrayToString(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)", referenced from:
antlr4::ParserRuleContext::toInfoString(antlr4::Parser*) in libantlr4-runtime.a(ParserRuleContext.o)
"antlrcpp::escapeWhitespace(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool)", referenced from:
antlr4::LexerNoViableAltException::toString() in libantlr4-runtime.a(LexerNoViableAltException.o)
antlr4::tree::Trees::toStringTree(antlr4::tree::ParseTree*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, bool) in libantlr4-runtime.a(Trees.o)
"antlrcpp::SingleWriteMultipleReadLock::readUnlock()", referenced from:
antlr4::atn::LexerATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(ParserATNSimulator.o)
"antlrcpp::SingleWriteMultipleReadLock::writeUnlock()", referenced from:
antlr4::atn::LexerATNSimulator::addDFAEdge(antlr4::dfa::DFAState*, unsigned long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::LexerATNSimulator::addDFAState(antlr4::atn::ATNConfigSet*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::adaptivePredict(antlr4::TokenStream*, unsigned long, antlr4::ParserRuleContext*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::atn::ParserATNSimulator::addDFAEdge(antlr4::dfa::DFA&, antlr4::dfa::DFAState*, long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::dfa::DFA::setPrecedenceStartState(int, antlr4::dfa::DFAState*, antlrcpp::SingleWriteMultipleReadLock&) in libantlr4-runtime.a(DFA.o)
"antlrcpp::SingleWriteMultipleReadLock::readLock()", referenced from:
antlr4::atn::LexerATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(ParserATNSimulator.o)
"antlrcpp::SingleWriteMultipleReadLock::writeLock()", referenced from:
antlr4::atn::LexerATNSimulator::addDFAEdge(antlr4::dfa::DFAState*, unsigned long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::LexerATNSimulator::addDFAState(antlr4::atn::ATNConfigSet*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::adaptivePredict(antlr4::TokenStream*, unsigned long, antlr4::ParserRuleContext*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::atn::ParserATNSimulator::addDFAEdge(antlr4::dfa::DFA&, antlr4::dfa::DFAState*, long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::dfa::DFA::setPrecedenceStartState(int, antlr4::dfa::DFAState*, antlrcpp::SingleWriteMultipleReadLock&) in libantlr4-runtime.a(DFA.o)
"antlrcpp::toMap(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)", referenced from:
antlr4::Recognizer::getRuleIndexMap() in libantlr4-runtime.a(Recognizer.o)
"antlrcpp::indent(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
antlr4::atn::ATN::toString() const in libantlr4-runtime.a(ATN.o)
"antlrcpp::finally(std::__1::function<void ()>)", referenced from:
Coral::CoralParser::unit() in CoralParser.o
Coral::CoralParser::assignment() in CoralParser.o
Coral::CoralParser::variable() in CoralParser.o
Coral::CoralParser::number() in CoralParser.o
Coral::CoralParser::expression(int) in CoralParser.o
antlr4::atn::LexerATNSimulator::match(antlr4::CharStream*, unsigned long) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::LexerATNSimulator::evaluatePredicate(antlr4::CharStream*, unsigned long, unsigned long, bool) in libantlr4-runtime.a(LexerATNSimulator.o)
...
"Guid::toString() const", referenced from:
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
"Guid::operator==(Guid const&) const", referenced from:
antlr4::atn::ATNDeserializer::isFeatureSupported(Guid const&, Guid const&) in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
"typeinfo for antlr4::ANTLRErrorListener", referenced from:
typeinfo for antlr4::ProxyErrorListener in libantlr4-runtime.a(ProxyErrorListener.o)
typeinfo for antlr4::BaseErrorListener in libantlr4-runtime.a(BaseErrorListener.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
根据缺少的符号输出,您需要至少再添加一个库到您的 LIBS。
无论提供什么:
Guid::*
antlr4::*
antlrcpp::*
你可以试试运行
ldd libantlr-runtime.so
要查看它希望link反对哪个库?
我正在尝试制作一个 SConstruct,它将...
- 将Antlr4 cpp runtime构建为静态库
- 使用 Antrl4(java 应用程序)以 cpp 格式构建 Lexer、Parser、Visitor 和 Listener,以获得简单的语法。
- 构建一个简单的程序来解析具有该语法的文件
全部在 Macos (Catalina) 上使用 Clang++
现在我不得不说我不是 C++ 专家,所以我可能遗漏了一些非常明显的东西......希望如此。
我遇到的问题是第一步和最后一步。
我可以构建 Antlr4 运行时,但稍后它不会 link 与最终程序。简单地调用 #include "antlr4-runtime.h"
会导致 Undefined symbols for architecture x86_64
错误。
奇怪的是,如果我使用 cmake 构建 Antlr4 运行时,如 Antlr 存储库中所述,那么 linking 问题就会消失。
所以我用 cmake 构建它并使用 VERBOSE 模式查看 make 如何构建各种目标文件并确保我使用与 Scons 相同的标志
cmake/make 的输出示例:
clang++
-Iantlr4-master/runtime/Cpp/runtime/src
-Iantlr4-master/runtime/Cpp/runtime/src/atn
-Iantlr4-master/runtime/Cpp/runtime/src/dfa
-Iantlr4-master/runtime/Cpp/runtime/src/misc
-Iantlr4-master/runtime/Cpp/runtime/src/support
-Iantlr4-master/runtime/Cpp/runtime/src/tree
-Iantlr4-master/runtime/Cpp/runtime/src/tree/pattern
-Iantlr4-master/runtime/Cpp/runtime/src/tree/xpath
-Wall -pedantic -W -std=c++11 -stdlib=libc++ -O3 -DNDEBUG -O3 -DNDEBUG
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants -std=gnu++11
-o CMakeFiles/antlr4_static.dir/src/atn/PredicateTransition.cpp.o
-c antlr4-master/runtime/Cpp/runtime/src/atn/PredicateTransition.cpp
显然这应该是一行,但为了更容易阅读,我分成了多行 ;)
所以我抓取了所有这些标志并将它们放入一个字符串中,让 Scons 弄清楚如何将它们应用到环境中:
pf = env.ParseFlags('\
-Wall -pedantic -W -O3 -std=c++11 -stdlib=libc++ -DNDEBUG -std=gnu++11 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk \
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants')
env.MergeFlags(pf)
现在我用 SCons 再次构建了 Antlr4,这是 SCons 创建的命令示例:
clang++
-o antlr4-master/runtime/Cpp/runtime/src/atn/PredicateTransition.o
-c
-std=c++11 -stdlib=libc++ -Wall -pedantic -W -O3
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants -DNDEBUG
-Iantlr4-master/runtime/Cpp/runtime/src
antlr4-master/runtime/Cpp/runtime/src/atn/PredicateTransition.cpp
我再次分成多行只是为了便于阅读...
我注意到的第一件事是命令中参数的顺序在 SCons 中无处不在,但其余部分几乎相同。
不幸的是,这给了我同样的 Undefined symbols for architecture x86_64
错误。
可能你注意到我只包含了 antlr4 运行时的主目录,这应该可以工作,因为所有的包含都从那个目录开始......无论如何,我也尝试像 cmake/make 那样包含所有子文件夹,结果是一样的。
我现在真的是一头雾水。希望你们中的一些人能够为我指明正确的方向。
这是我的 SConstruct 文件(路径与示例不同。但应该无关紧要)
import os
import subprocess
env = Environment(
CC = "clang",
CXX = "clang++",
CXXFLAGS = ['-std=c++11', '-stdlib=libc++'],
LINKFLAGS = ['-stdlib=libc++'],
)
env.Append(ENV = {'CLASSPATH': './dependencies/antlr4/antlr-4.8-complete.jar'})
#
# Builder for generating grammar files with antlr4 (the java app)
#
def antlr_emitter(target, source, env):
root = os.path.splitext(source[0].name)[0]
target = ['./src/Parser/{}{}.cpp'.format(root, p) for p in (
'BaseListener',
'BaseVisitor',
'Lexer',
'Listener',
'Parser',
'Visitor'
)]
return target, source
AntlrBuilder = Builder(
action='java org.antlr.v4.Tool $SOURCE -Dlanguage=Cpp -package Coral -visitor -listener -o src/Parser',
emitter=antlr_emitter
)
env.Append(BUILDERS={'Antlr': AntlrBuilder})
#
# Cloning the Environment for Antlr4 runtime
#
antlrEnv = env.Clone()
pf = antlrEnv.ParseFlags('\
-Wall -pedantic -W -O3 -DNDEBUG -std=gnu++11 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk \
-Wno-overloaded-virtual -Wno-dollar-in-identifier-extension -Wno-four-char-constants')
antlrEnv.MergeFlags(pf)
#
# Building in 3 steps, first the antlr4 runtime library, then the parser files with Antlr then the final program
#
AntlrRuntime = antlrEnv.Library(
'antlr4-runtime',
source =
Glob('./dependencies/antlr4Runtime/*.cpp') + \
Glob('./dependencies/antlr4Runtime/atn/*.cpp') + \
Glob('./dependencies/antlr4Runtime/dfa/*.cpp') + \
Glob('./dependencies/antlr4Runtime/misc/*.cpp') + \
Glob('./dependencies/antlr4Runtime/support/.cpp') + \
Glob('./dependencies/antlr4Runtime/tree/*.cpp') + \
Glob('./dependencies/antlr4Runtime/tree/pattern/*.cpp') + \
Glob('./dependencies/antlr4Runtime/tree/xpath/*.cpp'),
CPPPATH = './dependencies/antlr4Runtime',
ARFLAGS = 'qc'
)
ParserFiles = env.Antlr(source='Coral.g4')
CoralLang = env.Program(target = 'coral',
source = Glob('./src/*.cpp') + Glob('./src/Parser/*.cpp'),
CPPPATH = ['./src', './dependencies/antlr4Runtime'],
LIBPATH = '.',
LIBS = 'antlr4-runtime'
)
Requires(ParserFiles, AntlrRuntime)
Depends(CoralLang, ParserFiles)
Clean(ParserFiles, Glob('./src/Parser/*'))
最后是 main.cpp 文件。如您所见,它什么都没有,只是对 antlr 运行时的包含,这足以看到错误。
#include <cstdio>
#include "antlr4-runtime.h"
int main(int argc, const char *argv[])
{
if (!argv[1]) {
printf("hey! pass at least a file to parse...");
return 0;
}
else {
printf("parsing %s\n", argv[1]);
}
return 1;
}
尝试构建具有相对错误的程序时,整个 SCons 的输出是这样的:
clang++ -o src/Parser/CoralParser.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralParser.cpp
clang++ -o src/Parser/CoralBaseVisitor.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralBaseVisitor.cpp
clang++ -o src/Parser/CoralListener.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralListener.cpp
clang++ -o src/Parser/CoralVisitor.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralVisitor.cpp
clang++ -o src/Parser/CoralBaseListener.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralBaseListener.cpp
clang++ -o src/Parser/CoralLexer.o -c -std=c++11 -stdlib=libc++ -Isrc -Idependencies/antlr4Runtime src/Parser/CoralLexer.cpp
clang++ -o coral -stdlib=libc++ src/main.o src/Parser/CoralBaseListener.o src/Parser/CoralBaseVisitor.o src/Parser/CoralLexer.o src/Parser/CoralListener.o src/Parser/CoralParser.o src/Parser/CoralVisitor.o -L. -lantlr4-runtime
Undefined symbols for architecture x86_64:
"Guid::Guid(unsigned short const*, bool)", referenced from:
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::toUUID(unsigned short const*, unsigned long) in libantlr4-runtime.a(ATNDeserializer.o)
"Guid::Guid(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
antlr4::atn::ATNDeserializer::ADDED_PRECEDENCE_TRANSITIONS() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::ADDED_LEXER_ACTIONS() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::ADDED_UNICODE_SMP() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::SERIALIZED_UUID() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::BASE_SERIALIZED_UUID() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::SUPPORTED_UUIDS() in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
...
"Guid::Guid(Guid const&)", referenced from:
antlr4::atn::ATNDeserializer::SUPPORTED_UUIDS() in libantlr4-runtime.a(ATNDeserializer.o)
"antlr4::ANTLRErrorListener::~ANTLRErrorListener()", referenced from:
antlr4::Recognizer::Recognizer() in libantlr4-runtime.a(Recognizer.o)
antlr4::Recognizer::~Recognizer() in libantlr4-runtime.a(Recognizer.o)
antlr4::ProxyErrorListener::~ProxyErrorListener() in libantlr4-runtime.a(ProxyErrorListener.o)
antlr4::ProxyErrorListener::~ProxyErrorListener() in libantlr4-runtime.a(ProxyErrorListener.o)
antlr4::ConsoleErrorListener::~ConsoleErrorListener() in libantlr4-runtime.a(ConsoleErrorListener.o)
antlr4::ConsoleErrorListener::~ConsoleErrorListener() in libantlr4-runtime.a(ConsoleErrorListener.o)
antlr4::BaseErrorListener::~BaseErrorListener() in libantlr4-runtime.a(BaseErrorListener.o)
...
"antlrcpp::replaceAll(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
antlr4::Recognizer::getTokenErrorDisplay(antlr4::Token*) in libantlr4-runtime.a(Recognizer.o)
antlr4::DefaultErrorStrategy::escapeWSAndQuote(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const in libantlr4-runtime.a(DefaultErrorStrategy.o)
antlr4::CommonToken::toString(antlr4::Recognizer*) const in libantlr4-runtime.a(CommonToken.o)
"antlrcpp::arrayToString(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)", referenced from:
antlr4::ParserRuleContext::toInfoString(antlr4::Parser*) in libantlr4-runtime.a(ParserRuleContext.o)
"antlrcpp::escapeWhitespace(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool)", referenced from:
antlr4::LexerNoViableAltException::toString() in libantlr4-runtime.a(LexerNoViableAltException.o)
antlr4::tree::Trees::toStringTree(antlr4::tree::ParseTree*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, bool) in libantlr4-runtime.a(Trees.o)
"antlrcpp::SingleWriteMultipleReadLock::readUnlock()", referenced from:
antlr4::atn::LexerATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(ParserATNSimulator.o)
"antlrcpp::SingleWriteMultipleReadLock::writeUnlock()", referenced from:
antlr4::atn::LexerATNSimulator::addDFAEdge(antlr4::dfa::DFAState*, unsigned long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::LexerATNSimulator::addDFAState(antlr4::atn::ATNConfigSet*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::adaptivePredict(antlr4::TokenStream*, unsigned long, antlr4::ParserRuleContext*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::atn::ParserATNSimulator::addDFAEdge(antlr4::dfa::DFA&, antlr4::dfa::DFAState*, long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::dfa::DFA::setPrecedenceStartState(int, antlr4::dfa::DFAState*, antlrcpp::SingleWriteMultipleReadLock&) in libantlr4-runtime.a(DFA.o)
"antlrcpp::SingleWriteMultipleReadLock::readLock()", referenced from:
antlr4::atn::LexerATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::getExistingTargetState(antlr4::dfa::DFAState*, unsigned long) in libantlr4-runtime.a(ParserATNSimulator.o)
"antlrcpp::SingleWriteMultipleReadLock::writeLock()", referenced from:
antlr4::atn::LexerATNSimulator::addDFAEdge(antlr4::dfa::DFAState*, unsigned long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::LexerATNSimulator::addDFAState(antlr4::atn::ATNConfigSet*) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::ParserATNSimulator::adaptivePredict(antlr4::TokenStream*, unsigned long, antlr4::ParserRuleContext*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::atn::ParserATNSimulator::addDFAEdge(antlr4::dfa::DFA&, antlr4::dfa::DFAState*, long, antlr4::dfa::DFAState*) in libantlr4-runtime.a(ParserATNSimulator.o)
antlr4::dfa::DFA::setPrecedenceStartState(int, antlr4::dfa::DFAState*, antlrcpp::SingleWriteMultipleReadLock&) in libantlr4-runtime.a(DFA.o)
"antlrcpp::toMap(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)", referenced from:
antlr4::Recognizer::getRuleIndexMap() in libantlr4-runtime.a(Recognizer.o)
"antlrcpp::indent(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
antlr4::atn::ATN::toString() const in libantlr4-runtime.a(ATN.o)
"antlrcpp::finally(std::__1::function<void ()>)", referenced from:
Coral::CoralParser::unit() in CoralParser.o
Coral::CoralParser::assignment() in CoralParser.o
Coral::CoralParser::variable() in CoralParser.o
Coral::CoralParser::number() in CoralParser.o
Coral::CoralParser::expression(int) in CoralParser.o
antlr4::atn::LexerATNSimulator::match(antlr4::CharStream*, unsigned long) in libantlr4-runtime.a(LexerATNSimulator.o)
antlr4::atn::LexerATNSimulator::evaluatePredicate(antlr4::CharStream*, unsigned long, unsigned long, bool) in libantlr4-runtime.a(LexerATNSimulator.o)
...
"Guid::toString() const", referenced from:
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
"Guid::operator==(Guid const&) const", referenced from:
antlr4::atn::ATNDeserializer::isFeatureSupported(Guid const&, Guid const&) in libantlr4-runtime.a(ATNDeserializer.o)
antlr4::atn::ATNDeserializer::deserialize(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) in libantlr4-runtime.a(ATNDeserializer.o)
"typeinfo for antlr4::ANTLRErrorListener", referenced from:
typeinfo for antlr4::ProxyErrorListener in libantlr4-runtime.a(ProxyErrorListener.o)
typeinfo for antlr4::BaseErrorListener in libantlr4-runtime.a(BaseErrorListener.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
根据缺少的符号输出,您需要至少再添加一个库到您的 LIBS。 无论提供什么:
Guid::*
antlr4::*
antlrcpp::*
你可以试试运行
ldd libantlr-runtime.so
要查看它希望link反对哪个库?