I have compiled ANTLR4 runtime in a VirtualBox Ubuntu 20.04, with g++ 9.4.0.
I want to learn how to integrate the ANTLR tool into a Cpp project, So I compiled the antlr4 runtime with demo. The compilation was sucessfull, but when I try to run the built elf file. The following error occurs, the error occurs at the initialization of the Lexer. it seems that __gthread is not started.
Breakpoint 1, main () at /home/zhao/Downloads/antlr4/runtime/Cpp/demo/Linux/main.cpp:22
22 int main(int , const char **) {
(gdb) n
23 ANTLRInputStream input(u8"🍴 = 🍐 + \"😎\";(((x * π))) * µ + ∰; a + (x * (y ? 0 : 1) + z);");
(gdb) n
24 TLexer lexer(&input);
(gdb) s
antlrcpptest::TLexer::TLexer (this=0x7fffffffdb20, input=0x7fffffffda50) at /home/zhao/Downloads/antlr4/runtime/Cpp/demo/generated/TLexer.cpp:171
171 TLexer::TLexer(CharStream *input) : Lexer(input) {
(gdb) n
172 TLexer::initialize();
(gdb) s
antlrcpptest::TLexer::initialize () at /home/zhao/Downloads/antlr4/runtime/Cpp/demo/generated/TLexer.cpp:272
272 void TLexer::initialize() {
(gdb) s
273 std::call_once(tlexerLexerOnceFlag, tlexerLexerInitialize);
(gdb) s
std::call_once<void (&)()> (__once=..., __f=@0x7fffffffda00: {void (void)} 0x7fffffffda00) at /usr/include/c++/9/mutex:666
666 call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
(gdb) s
670 auto __callable = [&] {
(gdb)
675 __once_callable = std::__addressof(__callable); // NOLINT: PR 82481
(gdb)
std::__addressof<std::call_once<void (&)()>(std::once_flag&, void (&)())::{lambda()#1}>(void (&)()) (__r=...) at /usr/include/c++/9/bits/move.h:47
47 __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
(gdb)
48 { return __builtin_addressof(__r); }
(gdb)
std::call_once<void (&)()> (__once=..., __f=@0x55555556b4c3: {void (void)} 0x55555556b4c3 <(anonymous namespace)::tlexerLexerInitialize()>)
at /usr/include/c++/9/mutex:675
675 __once_callable = std::__addressof(__callable); // NOLINT: PR 82481
(gdb)
676 __once_call = []{ (*(decltype(__callable)*)__once_callable)(); };
(gdb)
std::call_once<void (&)()>(std::once_flag&, void (&)())::{lambda()#2}::operator void (*)()() const (this=0x7fffffffda00) at /usr/include/c++/9/mutex:676
676 __once_call = []{ (*(decltype(__callable)*)__once_callable)(); };
(gdb)
std::call_once<void (&)()> (__once=..., __f=@0x55555556b4c3: {void (void)} 0x55555556b4c3 <(anonymous namespace)::tlexerLexerInitialize()>)
at /usr/include/c++/9/mutex:683
683 int __e = __gthread_once(&__once._M_once, &__once_proxy);
(gdb)
__gthread_once (__once=0x5555556e32bc <(anonymous namespace)::tlexerLexerOnceFlag>, __func=0x7ffff7eabc20 <__once_proxy>)
at /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:699
699 if (__gthread_active_p ())
(gdb) s
__gthread_active_p () at /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:252
252 return __gthread_active_ptr != 0;
(gdb) display __gthread_active_ptr
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
253 }
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
__gthread_once (__once=0x5555556e32bc <(anonymous namespace)::tlexerLexerOnceFlag>, __func=0x7ffff7eabc20 <__once_proxy>)
at /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:699
699 if (__gthread_active_p ())
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
702 return -1;
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
703 }
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
std::call_once<void (&)()> (__once=..., __f=@0x55555556b4c3: {void (void)} 0x55555556b4c3 <(anonymous namespace)::tlexerLexerInitialize()>)
at /usr/include/c++/9/mutex:690
690 if (__e)
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
691 __throw_system_error(__e);
I tried looking up in the CMakeLists but cannot find where the gthread package is linked. Besides, I am using a newly installed ubuntu 20.04. If it is a dependency issue please tell me which package to install.
Thank you! Best Zhao
So I had this same problem and all I could find online was a suggestion to add
find_package(Threads REQUIRED)
target_link_libraries(MyTarget Threads::Threads)
to the Cmake files. However, I soon realised that this solution had already been implemented as part of a patch pushed earlier in the year, but the issue was not resolved for me...
What was actually needed in my case was to set the cmake variable THREADS_PREFER_PTHREAD_FLAG to ON i.e. set(THREADS_PREFER_PTHREAD_FLAG ON)
. By doing this, Cmake will pass the flag -pthread to the compiler and linker instead of -lpthread. This solved all my issues.
Full breakdown to build Cpp runtime and demo with -pthread flag
Assuming you already have antlr4 installed using apt (or built manually), using the command line, go to your desired directory and clone the antlr4 repository (if you haven't already done so):
git clone https://github.com/antlr/antlr4.git
Now generate all the lexer and parser files need for the demo as follows:
cd antlr4/runtime/Cpp/demo
antlr4 -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
cd ..
This will create multiple files and store them in demo/generated/.
From the <antlr4-dir>/runtime/Cpp directory, where <antlr4-dir> is the location you cloned the git repository, edit both CMakeLists.txt and demo/CMakeLists.txt adding
set(THREADS_PREFER_PTHREAD_FLAG ON)
to both files and save.
Back to the command line, from location <antlr4-dir>/runtime/Cpp
mkdir build && mkdir run && cd build
whereis antlr4
the whereis command will result in the location of the antlr4 package you installed through apt (or manually installed). Lets say this location is <apt_loc_antlr4>/antlr4
, where <apt_loc_antlr4> is a location on your machine. You will need to substitute this location in the next command:
cmake .. -DANTLR_JAR_LOCATION=<apt_loc_antlr4>/antlr4 -DCMAKE_CXX_STANDARD=17 -DWITH_DEMO=True
make
Assuming all the above worked, you should now be able to run the demo.
cd demo/
./antlr4-demo