tudat-team / tudatpy

A Python platform to perform astrodynamics and space research.
https://tudat-space.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
29 stars 30 forks source link

Undefined symbol: _ZTVN5boost9unit_test15unit_test_log_tE #3

Closed geoffreygarrett closed 5 years ago

geoffreygarrett commented 5 years ago

Reproduction of error:

Clone forked tudatBundle and build: Some changes will need to be made to the tudatBundle. I have made modifications on my fork of the repository below. Be sure to checkout the feature/tudatpy branch. Repository: https://github.com/ggarrett13/tudatBundle.git Branch: feature/tudatpy

git clone -b feature/tudatpy https://github.com/ggarrett13/tudatBundle.git

cd tudatBundle

git submodule update --init --recursive

mkdir build

cd build

cmake ..

make -j$(nproc)

Check 2/3 tests pass: cd tudatpy && make test

Running tests...
Test project /home/ggarrett/Repositories/WORK/tudatBundle/build/tudatpy
    Start 1: to_python_conversion
1/3 Test #1: to_python_conversion .............   Passed    0.06 sec
    Start 2: constants
2/3 Test #2: constants ........................   Passed    0.04 sec
    Start 3: environment_setup
3/3 Test #3: environment_setup ................***Failed    0.04 sec

67% tests passed, 1 tests failed out of 3

Total Test time (real) =   0.14 sec

The following tests FAILED:
          3 - environment_setup (Failed)
Errors while running CTest
Makefile:95: recipe for target 'test' failed
make: *** [test] Error 8

Invoke python unittest framework for verbose output: python3 -m unittest -v test/test_environment_setup.py (Note: This may fail if missing a python dependency, as I have not included a setup.py file as of yet. If so, install manually with pip3).

test_environment_setup (unittest.loader._FailedTest) ... ERROR

======================================================================
ERROR: test_environment_setup (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_environment_setup
Traceback (most recent call last):
  File "/usr/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName
    module = __import__(module_name)
  File "/home/ggarrett/Repositories/WORK/tudatBundle/build/tudatpy/test/test_environment_setup.py", line 1, in <module>
    from tudatpy.simulation.environment import get_default_body_settings
  File "/home/ggarrett/Repositories/WORK/tudatBundle/build/tudatpy/tudatpy/simulation/environment/__init__.py", line 1, in <module>
    from ._environment import *
ImportError: /home/ggarrett/Repositories/WORK/tudatBundle/build/tudatpy/tudatpy/simulation/environment/_environment.so: undefined symbol: _ZTVN5boost9unit_test15unit_test_log_tE

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

This issue occurs during the invocation of the tudat::simulation_setup::createBodies() function. Line 54-56 of tudatpy/tudatpy/simulation/environment/_environment.cpp.

tss::NamedBodyMap createBodiesWrapped(stdBodySettingsPointerMap bodySettings) {
    return tss::createBodies(bodySettings);
}
/** NOTE: Wrapping the function is technically superfluous, 
   * it was a direction I attempted to isolate the cause.
   */

Commenting out line 54-56 of tudatpy/tudatpy/simulation/environment/_environment.cpp and commenting out lines [2, 45, 46, 47] in test/test_environment_setup.py results in the following when running: make -j$(nproc) && python3 -m unittest -v test/test_environment_setup.py in tudatBundle/build/tudatpy.

 python3 -m unittest -v test/test_environment_setup.py
test_base_ephemeris_type (test.test_environment_setup.TestBody) ... ok
test_body_settings_basic (test.test_environment_setup.TestBody) ... ok
test_default_body_settings (test.test_environment_setup.TestBody) ... ok
test_ephemeris_settings (test.test_environment_setup.TestBody) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.018s

OK

Okay so at this point we know what is causing the error, but why, I do not know. Here are a few thoughts that I have from the work experience so far and from what I've been reading online.

1) The issue at hand is a failure to link the relevant libraries in boost to the target of _environment.cpp. The linking is done on lines 246 - 256 of the CMakelist.txt under tudatpy using the deprecated link_libraries command (This will be replaced later with target_link_libraries so as to only include the needed libraries per target).

link_libraries(
        ${Boost_LIBRARIES}
        ${Boost_LOG_LIBRARY}
        ${Boost_TEST_LIBRARY}
        ${Boost_FILESYSTEM_LIBRARY}
        ${Boost_SYSTEM_LIBRARY}
        ${PYTHON_LIBRARIES}
        ${tudat_basic_mathematics}
        ${TUDAT_PROPAGATION_LIBRARIES}
        ${boost_numpy_eigen}
        ${LIBROOT}/libboost_numpy_eigen.so) # Deprecated but so convenient!

I had a similar linking issue with an undefined symbol with a name indicating it was from from Boost_SYSTEM_LIBRARY, including this in the linking resolved that issue. I therefore attempted to explicitly link Boost_LOG_LIBRARY and Boost_TEST_LIBRARY based on the name of the undefined symbol: _ZTVN5boost9unit_test15unit_test_log_tE. This did not work.

2) https://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/rationale/namespace_mangling.html

3) I attempted the following at the top of the _environment.cpp file which dealt with undefined reference errors that others encountered. (Changed nothing)

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

In conclusion I'll see if I can use some duct tape and get the library to the unittest linked somehow, but I'd appreciate a hand @DominicDirkx.

geoffreygarrett commented 5 years ago

Update (Further attempt, no success): I attempted to manually define the paths to the boost_unittest_framework, boost_log, and tudat_environment_setup in hopes that it was a problem linking to the libraries. I still received the same error regarding the _ZTVN5boost9unit_test15unit_test_log_tE which is part of the Header <boost/test/unit_test_log.hpp> (source: Boost.Test).

set(Boost_UNITTEST_LIBRARY /home/ggarrett/Repositories/WORK/tudatBundle/boost/stage/lib/libboost_unit_test_framework-mt.a)
set(Boost_LOG_LIBRARY /home/ggarrett/Repositories/WORK/tudatBundle/boost/stage/lib/libboost_log-mt.a)
set(Boost_LOGSETUP_LIBRARY /home/ggarrett/Repositories/WORK/tudatBundle/boost/stage/lib/libboost_log_setup-mt.a)
set(tudat_environment_setup /home/ggarrett/Repositories/WORK/tudatBundle/tudat/lib/libtudat_environment_setup.a)

message("CIAO ${Boost_LOG_LIBRARY}")
message("CIAO ${Boost_LOGSETUP_LIBRARY}")
message("CIAO ${Boost_UNITTEST_LIBRARY}")
message("CIAO ${Boost_SYSTEM_LIBRARY}")

link_libraries(
        ${Boost_LIBRARIES}
        ${Boost_LOG_LIBRARY}
        ${Boost_UNITTEST_LIBRARY}
        ${Boost_LOGSETUP_LIBRARY}
        ${Boost_SYSTEM_LIBRARY}
        ${PYTHON_LIBRARIES}
        ${tudat_basic_mathematics}
        ${TUDAT_PROPAGATION_LIBRARIES}
        ${tudat_environment_setup}
#        ${boost_numpy_eigen}
        ${LIBROOT}/libboost_numpy_eigen.so) # Deprecated but so convenient!

I do not understand why it is not correctly linking to the Boost.Test library, or why it is even required to compile a usable reference to the function createBodies.