我正在尝试创建一个将要...的SConstruct ...
全部在Macos(Catalina)上使用Clang ++
现在我不得不说我不是C ++专家,所以可能我想念的东西很明显……希望。
我遇到的问题是第一步和最后一步。我可以构建Antlr4运行时,但稍后不会与最终程序链接。仅仅调用#include "antlr4-runtime.h"
会导致Undefined symbols for architecture x86_64
错误。
奇怪的是,如果我用cmake构建Antlr4运行时,如Antlr的存储库中所述,那么链接问题就消失了。
所以我用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运行时的主目录,该目录应该可以正常工作,因为所有include都从该目录开始...无论如何,我也尝试像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)
我正在尝试创建一个SConstruct,将...将Antlr4 cpp运行时构建为静态库使用Antrl4(java应用程序)以简单的语法以cpp格式构建Lexer,Parser,Visitor和Listener。 ...
基于缺少的符号输出,您需要至少再添加一个库到LIBS。无论提供什么: