I'm getting the following error with GCC >=9 and std>=11 merely by adding the header (MacOSX on MacBook Pro 2020 and armadillo installed with Homebrew and the code is compiled with standard CMake configuration)
#include <armadillo>
to my project.
Undefined symbols for architecture x86_64: "___emutls_v._ZN4arma19mt19937_64_instanceE", referenced from: __GLOBAL__sub_I_Test_HPP.cpp in Test_HPP.cpp.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status make[2]: *** [Test_HPP] Error 1 make[1]: *** [CMakeFiles/Test_HPP.dir/all] Error 2
I've tried various hacks including optimization flags e.g. O2, O3 etc. but finally adding the preprocessor header
#define ARMA_DONT_USE_WRAPPER
apparently resolved the issue for now but I need an explanation to feel settled. If the above pre-processor is absolutely necessary to compile the code, should the armadillo library maintainers absorb the macro within the library itself? This kind of issues may take a lot of time to resolve as it is not originated in any programming logic.
The preprocessor directive ARMA_DONT_USE_WRAPPER
disables code that uses thread_local
which depends on emutls
in gcc
on macOS. This appears unsupported on macOS 11 (Big Sur) according to the maintainers of Armadillo. As shown here CMakeLists.txt.
A related workaround is provided by the maintainers Commit 83e48f8c in file include/armadillo_bits/arma_rng.hpp
I'm unable to confirm why it is unsupported in macOS or Homebrew but from other doc, it looks like trying a different build system configuration with correct TLS support might fix the issue e.g ugrading gcc
or maybe rebuilding gcc
with the --enable-tls
switch. I'm using Catalina and my gcc
version installed with Homebrew is 11.1.0
. If you need gcc
version 9 you can switch between them using the brew link <package>@<version>
command.