Saya mencoba membuat SConstruct yang akan ...

  • Buat Antlr4 cpp runtime sebagai pustaka statis
  • Gunakan Antrl4 (aplikasi java) untuk membuat Lexer, Parser, Visitor, dan Listener, dalam format cpp, untuk tata bahasa yang sederhana.
  • Buat program sederhana untuk mengurai file dengan tata bahasa itu

Semua menggunakan Dentang++ di Macos (Catalina)

Sekarang adalah di mana saya harus mengatakan bahwa saya bukan ahli dalam C++, jadi mungkin saya melewatkan sesuatu yang sangat jelas... mudah-mudahan.

Masalah yang saya miliki adalah pada langkah pertama dan terakhir. Saya dapat membangun runtime Antlr4 tetapi kemudian tidak terhubung dengan program akhir. Cukup memanggil #include "antlr4-runtime.h" menghasilkan kesalahan Undefined symbols for architecture x86_64.

Yang aneh adalah, jika saya membangun runtime Antlr4 dengan cmake, seperti yang dijelaskan di repositori Antlr, maka masalah penautan akan hilang.

Jadi saya membuatnya dengan cmake dan menggunakan mode VERBOSE untuk melihat bagaimana membuat berbagai file objek dan memastikan bahwa saya menggunakan flag yang sama dengan Scons

Contoh output dengan 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

Jelas ini seharusnya menjadi satu baris tetapi saya membaginya menjadi beberapa baris agar lebih mudah dibaca;)

Jadi saya mengambil semua flag itu dan memasukkannya ke dalam string dan membiarkan Scons mencari cara untuk menerapkannya ke lingkungan:

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)

Sekarang saya membangun Antlr4 lagi dengan SCons dan ini adalah contoh perintah yang dibuat 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

Sekali lagi saya membagi beberapa baris hanya untuk membuatnya mudah dibaca ...

Hal pertama yang saya perhatikan adalah bahwa urutan argumen dalam perintah ada di mana-mana di SCons tetapi sisanya hampir sama. Sayangnya, ini memberi saya kesalahan Undefined symbols for architecture x86_64 yang sama.
Mungkin Anda memperhatikan bahwa saya hanya menyertakan direktori utama runtime antlr4, yang seharusnya berfungsi karena semua penyertaan dimulai dari direktori itu ... Bagaimanapun, saya juga mencoba memasukkan semua subfolder seperti yang dilakukan cmake/make, hasilnya adalah sama.

Aku benar-benar tidak tahu apa-apa saat ini. Semoga beberapa dari Anda akan dapat menempatkan saya ke arah yang benar.

Ini adalah file SConstruct saya (jalur berbeda dari contoh. tetapi seharusnya tidak masalah)

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/*'))

Dan terakhir ini adalah file main.cpp. Seperti yang Anda lihat tidak ada apa-apa, hanya menyertakan ke antlr runtime dan itu sudah cukup untuk melihat kesalahannya.

#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;
}

Seluruh keluaran SCons ketika mencoba membangun program dengan kesalahan relatif adalah ini:

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)
0
Dan Niero 23 Mei 2020, 15:48

1 menjawab

Jawaban Terbaik

Berdasarkan keluaran simbol yang hilang, Anda perlu menambahkan setidaknya satu pustaka lagi ke LIBS Anda. Apa pun yang menyediakan:

   Guid::*
   antlr4::*
   antlrcpp::*

Anda mungkin mencoba berlari

ldd libantlr-runtime.so

Untuk melihat perpustakaan apa yang diharapkan untuk ditautkan?

0
bdbaddog 25 Mei 2020, 03:16