gflags: undefined reference to 'FlagRegisterer::FlagRegisterer'

I installed gflags first, and then failed to install glog. src/logging_unittest-logging_unittest.o: In function '__static_initialization_and_destruction_0': /opt/packages/glog-0.3.4/src/googletest.h:93: undefined reference to '::FlagRegisterer::FlagRegisterer<std::string>(char const*, char const*, char const*, std::string*, std::string*)' /opt/packages/glog-0.3.4/src/googletest.h:94: undefined reference to 'google::FlagRegisterer::FlagRegisterer<std::string>(char const*, char const*, char const*, std::string*, std::string*)' /opt/packages/glog-0.3.4/src/googletest.h:96: undefined reference to 'google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)' /opt/packages/glog-0.3.4/src/googletest.h:100: undefined reference to 'google::FlagRegisterer::FlagRegisterer<int>(char const*, char const*, char const*, int*, int*)' collect2: error: ld returned 1 exit status make: *** [logging_unittest] Error 1

So, I removed all libs of gflags and reinstall the glog, it worked at that time. But, when I installed folly, it prompted a similar error. How to fix it? Who can help me?

make all-recursive make[1]: Entering directory '/opt/packages/folly/folly' Making all in . make[2]: Entering directory '/opt/packages/folly/folly' /bin/bash ./libtool --tag=CXX --mode=link g++ -std=gnu++0x -g -O2 -lboost_context -lboost_thread -lboost_filesystem -lboost_system -lboost_regex -lpthread -L/usr/local/include/double-conversion/ -o generate_fingerprint_tables build/GenerateFingerprintTables.o libfollybase.la -llzma -lz -lsnappy -llz4 -liberty -ljemalloc -levent -ldouble-conversion -lssl -lgflags -lglog libtool: link: g++ -std=gnu++0x -g -O2 -o generate_fingerprint_tables build/GenerateFingerprintTables.o -L/usr/local/include/double-conversion/ ./.libs/libfollybase.a -lboost_context -lboost_thread -lboost_filesystem -lboost_system -lboost_regex -lpthread -llzma -lz -lsnappy -llz4 -liberty -ljemalloc -levent -ldouble-conversion -lssl -lgflags -lglog /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libglog.so: undefined reference to 'google::FlagRegisterer::FlagRegisterer(char const*, char const*, char const*, char const*, void*, void*)' collect2: error: ld returned 1 exit status make[2]: *** [generate_fingerprint_tables] Error 1 make[2]: Leaving directory '/opt/packages/folly/folly' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/opt/packages/folly/folly' make: *** [all] Error 2

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 18 (6 by maintainers)

Most upvoted comments

I saw so many doc,but could not find a solution.WTF.

I have the same problem and this is my fix:

  1. git clone gflags
  2. ccmake your gflags and configure to build gflags with shared lib.
  3. cmake, make and make install your gflags
  4. git clone glog
  5. export LDFLAGS=‘-L/usr/local/lib’ # since my gflags lib is installed under /usr/local/lib
  6. cd ${your_glog_folder} && ./configure && make
  7. make install

With gflags complied to shared lib and LDFLAGS set, it’s works on my ubuntu.

Some notes to help resolve these undefined reference issues:

  • The “solution” of uninstalling curl cannot be a real fix. Don’t.

  • Regarding the original report from Jan 2017:

    • The FlagRegisterer constructor was changed in Jul 2017 to a template function.
  • The default namespace of both gflags and glog libraries is google.

    • Hence, unless GFLAGS_NAMESPACE was modified, the namespace should be fine.
  • When building the gflags library on macOS 10.12 with clang:

     git clone https://github.com/gflags/gflags.git
     cd gflags
     mkdir builds/release
     cd builds/release
     cmake ../..
     make
    

    All expected explicit template instantiations of the FlagRegisterer constructor are present:

    Apple LLVM version 8.0.0 (clang-800.0.42.1)
    Target: x86_64-apple-darwin16.7.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    
    > nm lib/libgflags.a | grep FlagRegisterer | c++filt
    0000000000000000 T google::FlagRegisterer::FlagRegisterer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const*, char const*, char const*, 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> >*)
    00000000000003b0 T google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)
    0000000000000810 T google::FlagRegisterer::FlagRegisterer<double>(char const*, char const*, char const*, double*, double*)
    0000000000000490 T google::FlagRegisterer::FlagRegisterer<int>(char const*, char const*, char const*, int*, int*)
    0000000000000570 T google::FlagRegisterer::FlagRegisterer<unsigned int>(char const*, char const*, char const*, unsigned int*, unsigned int*)
    0000000000000650 T google::FlagRegisterer::FlagRegisterer<long long>(char const*, char const*, char const*, long long*, long long*)
    0000000000000730 T google::FlagRegisterer::FlagRegisterer<unsigned long long>(char const*, char const*, char const*, unsigned long long*, unsigned long long*)
    0000000000000880 T google::FlagRegisterer::FlagRegisterer<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const*, char const*, char const*, 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> >*)
    0000000000000090 T google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)
    00000000000007a0 T google::FlagRegisterer::FlagRegisterer<double>(char const*, char const*, char const*, double*, double*)
    0000000000000420 T google::FlagRegisterer::FlagRegisterer<int>(char const*, char const*, char const*, int*, int*)
    0000000000000500 T google::FlagRegisterer::FlagRegisterer<unsigned int>(char const*, char const*, char const*, unsigned int*, unsigned int*)
    00000000000005e0 T google::FlagRegisterer::FlagRegisterer<long long>(char const*, char const*, char const*, long long*, long long*)
    00000000000006c0 T google::FlagRegisterer::FlagRegisterer<unsigned long long>(char const*, char const*, char const*, unsigned long long*, unsigned long long*)
    
  • When using the GCC 7.2 compiler installed using Homebrew, the symbol for std::string differs:

    0000000000002e90 T google::FlagRegisterer::FlagRegisterer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(char const*, char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)
    

    Note the std::__cxx11::basic_string instead of std::__1::basic_string.

  • This SO question may provide insight as to how to resolve linker error of undefined reference to google::FlagRegisterer::FlagRegisterer<std::__cxx11::basic_string[...].

  • If you build with GCC >=5.1 and see many undefined reference to google::FlagRegisterer::FlagRegisterer errors, not only for std::__cxx11::basic_string, you are probably trying to link with a gflags library that was built with a different compiler, e.g., clang. I could confirm this on macOS 10.12, where I had /usr/local/lib/libgflags.a built with clang still installed. Removing it and linking with the libgflags.a library built with the same GCC version then gave only one error:

    [ 45%] Linking CXX executable signalhandler_unittest
    Undefined symbols for architecture x86_64:
      "google::FlagRegisterer::FlagRegisterer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(char const*, char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)", referenced from:
      __static_initialization_and_destruction_0(int, int) in libglog.a(logging.cc.o)
      __static_initialization_and_destruction_0(int, int) in libglog.a(vlog_is_on.cc.o)
    ld: symbol(s) not found for architecture x86_64
    collect2: error: ld returned 1 exit status
    ```
    
  • Still using GCC 7.2, building both gflags and glog with CMAKE_CXX_FLAGS="-std=c++17 -D _GLIBCXX_USE_CXX11_ABI=0", we get the following output of nm | c++filt:

    > nm lib/libgflags.a | grep FlagRegisterer | c++filt
    0000000000001c10 T google::FlagRegisterer::FlagRegisterer<std::string>(char const*, char const*, char const*, std::string*, std::string*)
    

    But the linker error when building glog reads:

    Undefined symbols for architecture x86_64:
      "google::FlagRegisterer::FlagRegisterer<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >(char const*, char const*, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)"
    

    Note that in nm output it is std::string whereas the linker error refers to std::basic_string. This error persists for either setting of _GLIBCXX_USE_CXX11_ABI=0|1.

  • Note that using GCC 4.9 (before ABI change), linking glog with gflags library succeeds. Given that the built also works without issues with clang, it seems changes in GCC are responsible for the undefined reference issues.

To be continued…

If anybody face this problem, just uninstall curl and make sure there’s no libcurl files left in your /usr/local/lib 😉 That fixed it for me

Edited by @schuhschuh: curl has nothing to do with gflags and/or glog. Read on.

Hi I encounter the similar problem. Have you fixed this problem? What is the solution? My environment is : Ubuntu 14.04 LTS, cmake 3.2.2 gflags: latest version from Github master, installed using

ccmake..
make
sudo make install

glog: release 0.3.5, installed using

./configure
make
sudo make install

I didn’t set the namespace of these two lib explicitly. I encountered similar error during building glog: undefined reference to google::FlagRegisterer::FlagRegisterer But after I clean everything and re-build gflags and flog, passsed. Then I tried to build Google-Cartographer, failed again.

[ 70%] Linking CXX executable ../bin/libmv_homography
Building CXX object internal/ceres/CMakeFiles/autodiff_test.dir/autodiff_test.cc.o
/usr/local/lib/libglog.a(libglog_la-logging.o): In function `__static_initialization_and_destruction_0':
/home/arkin/ros_code/glog-0.3.5/src/logging.cc:106: undefined reference to `google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)'
/home/arkin/ros_code/glog-0.3.5/src/logging.cc:108: undefined reference to `google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)'
......

Is the error of making Cartographer caused by gflags and glog?

I was also not being able to compile glog from source and I was getting the same error.

In my case the culprit was /usr/lib/x86_64-linux-gnu/libgflags.a. It was in the system even after sudo apt-get purge libgflags-dev.

Sequence of commands I used to install protobuf, gflags and glog from source:

# Create symlinks to local bin such that compilers of version >= 5 are used.
ln -s /usr/bin/g++-5 ~/bin/g++

# Update .profile to add local bin to PATH
PATH=$HOME/bin:$HOME/.local/bin:$PATH

# Clone, build and install protobuf
cd protobuf-3.5.1/
sudo make uninstall
make clean
./autogen.sh 
./configure 
make -j6
sudo make install

# Purge and remove aptitude installed gflags
sudo rm /usr/lib/x86_64-linux-gnu/libgflag*

# Build and install gflags from source
cd gflags-master/
make clean
mkdir builds
cd builds/
cmake ..
make
sudo make install

# Build and install glog from source
cd glog-master/
make clean
./autogen.sh 
./configure 
make -j6
sudo make install

IT WAS BECAUSE TWO libgflags_nothreads.a CONFLICTS.

REMOVE ONE OF THEM !!!

which is usually installed in your local host’s /usr dir.