mujoco
mujoco copied to clipboard
How to build code that uses `mjCModel`?
As advised to me in #364 I tried to use mjCModel to build a model pragramatically.
However I get some undefined reference errors to some mjCModel member functions.
After some investigation, it seems that these symbols are indeed missing from the distributed shared libs, at least on linux x64.
On the downloaded .so, nm gives me:
> nm --demangle libmujoco.so|grep mjCModel::
00000000001d63a0 t mjCModel::AddExclude()
00000000001d7bc0 t mjCModel::FindObject(mjtObj_, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
00000000001d6a70 t mjCModel::NumObjects(mjtObj_)
00000000001d6540 t mjCModel::AddEquality(mjCDef*)
00000000001da1e0 t mjCModel::FuseReindex(mjCBody*)
00000000001d99e0 t mjCModel::IndexAssets()
00000000001d6f10 t mjCModel::AddDef(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int)
00000000001d6880 t mjCModel::AddKey()
00000000001d5e00 t mjCModel::AddMesh(mjCDef*)
00000000001d5fa0 t mjCModel::AddSkin()
00000000001db070 t mjCModel::Compile(mjVFS_ const*)
00000000001d6dc0 t mjCModel::FindDef(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
00000000001eca30 t mjCModel::CopyBack(mjModel_ const*)
00000000001d6200 t mjCModel::AddHField()
00000000001d66e0 t mjCModel::AddTendon(mjCDef*)
00000000001d6c10 t mjCModel::GetObject(mjtObj_, int)
00000000001d90e0 t mjCModel::MakeLists(mjCBody*)
00000000001d4410 t mjCModel::mjCModel()
00000000001d5000 t mjCModel::~mjCModel()
But if I compile the mujoco myself and run nm on the resulting .so I get this instead:
> nm --demangle lib/libmujoco.so|grep mjCModel::
0000000000171130 t mjCModel::AddExclude()
0000000000171100 t mjCModel::AddExclude() [clone .cold]
0000000000171f10 t mjCModel::AddNumeric()
0000000000171ee0 t mjCModel::AddNumeric() [clone .cold]
00000000001708e0 t mjCModel::AddTexture()
00000000001708b0 t mjCModel::AddTexture() [clone .cold]
000000000015bb40 t mjCModel::FindObject(mjtObj_, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
0000000000159f30 t mjCModel::FindObject(mjtObj_, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [clone .constprop.1]
000000000016e7d0 t mjCModel::FuseStatic()
000000000016e774 t mjCModel::FuseStatic() [clone .cold]
000000000015ba50 t mjCModel::IsCompiled()
000000000015b4c0 t mjCModel::NumObjects(mjtObj_)
0000000000171990 t mjCModel::AddActuator(mjCDef*)
0000000000171960 t mjCModel::AddActuator(mjCDef*) [clone .cold]
00000000001713d0 t mjCModel::AddEquality(mjCDef*)
00000000001713a0 t mjCModel::AddEquality(mjCDef*) [clone .cold]
0000000000170b80 t mjCModel::AddMaterial(mjCDef*)
0000000000170b50 t mjCModel::AddMaterial(mjCDef*) [clone .cold]
000000000016c470 t mjCModel::CopyObjects(mjModel_*)
000000000016ba20 t mjCModel::FuseReindex(mjCBody*)
000000000015d580 t mjCModel::IndexAssets()
000000000015d2d2 t mjCModel::IndexAssets() [clone .cold]
0000000000161e80 t mjCModel::LengthRange(mjModel_*, mjData_*)
0000000000161d4a t mjCModel::LengthRange(mjModel_*, mjData_*) [clone .cold]
000000000015e660 t mjCModel::SetDefaultNames()
000000000015e4d4 t mjCModel::SetDefaultNames() [clone .cold]
0000000000161920 t mjCModel::AutoSpringDamper(mjModel_*)
000000000015a0a0 t mjCModel::Clear()
00000000001688f0 t mjCModel::AddDef(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)
00000000001688d0 t mjCModel::AddDef(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int) [clone .cold]
00000000001726d0 t mjCModel::AddKey()
00000000001726a0 t mjCModel::AddKey() [clone .cold]
00000000001700e0 t mjCModel::AddMesh(mjCDef*)
00000000001700b0 t mjCModel::AddMesh(mjCDef*) [clone .cold]
0000000000170e60 t mjCModel::AddPair(mjCDef*)
0000000000170e30 t mjCModel::AddPair(mjCDef*) [clone .cold]
00000000001703b0 t mjCModel::AddSkin()
0000000000170380 t mjCModel::AddSkin() [clone .cold]
00000000001721b0 t mjCModel::AddText()
0000000000172180 t mjCModel::AddText() [clone .cold]
0000000000174800 t mjCModel::Compile(mjVFS_ const*)
0000000000173102 t mjCModel::Compile(mjVFS_ const*) [clone .cold]
000000000015bac0 t mjCModel::FindDef(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
0000000000172440 t mjCModel::AddTuple()
0000000000172410 t mjCModel::AddTuple() [clone .cold]
0000000000166cd0 t mjCModel::CopyBack(mjModel_ const*)
0000000000163790 t mjCModel::CopyTree(mjModel_*)
0000000000163648 t mjCModel::CopyTree(mjModel_*) [clone .cold]
000000000015ba60 t mjCModel::GetError()
000000000015bab0 t mjCModel::GetWorld()
000000000015f8f0 t mjCModel::SetSizes()
000000000015f8a2 t mjCModel::SetSizes() [clone .cold]
0000000000170640 t mjCModel::AddHField()
0000000000170610 t mjCModel::AddHField() [clone .cold]
0000000000171c70 t mjCModel::AddSensor()
0000000000171c40 t mjCModel::AddSensor() [clone .cold]
00000000001716b0 t mjCModel::AddTendon(mjCDef*)
0000000000171680 t mjCModel::AddTendon(mjCDef*) [clone .cold]
0000000000162ae0 t mjCModel::CopyNames(mjModel_*)
0000000000162a8a t mjCModel::CopyNames(mjModel_*) [clone .cold]
000000000015b6e0 t mjCModel::GetObject(mjtObj_, int)
000000000016bf60 t mjCModel::MakeLists(mjCBody*)
000000000016f900 t mjCModel::mjCModel()
000000000016f900 t mjCModel::mjCModel()
000000000016f5e0 t mjCModel::mjCModel() [clone .cold]
000000000015a260 t mjCModel::~mjCModel()
000000000015a260 t mjCModel::~mjCModel()
We should've mentioned it in the previous issue, but this isn't a bug. We deliberately avoid exposing a C++ ABI in our precompiled library.
If you want to experiment with mjCModel, you'll need to build MuJoCo from source alongside your own code. I'll rephrase the issue title, but leave it open so that you can ask more questions about this if necessary.
Ok thanks for the explanation.
But there is one more problem though, you need to add MJAPI
to classes in users
otherwise we can't link to them from the outside
That's true, but we are hesitant to export symbols that might change/disappear in the future.
If you don't mind adding MJAPI
in your codebase for now, that would be easiest. It should be trivial to to reconcile that change with future updates, at least until we start touching the compiler.
Let us know if that solution doesn't work for you for some reason.
A possibly better alternative is to statically link MuJoCo into your program, and build everything without -fvisibility=hidden
.
you'll need to build MuJoCo from source alongside your own code.
@saran-t Does this mean the CMakeLists.txt in the mujoco repo should be modified to include other packages for our / my own personal projects? I've been trying to include the mujoco library in my C++ project with my own CMakeLists.txt. Bringing mujoco into my project is not doable? I'm just trying to get a clear picture of what to do.
I'm somewhat new to cmake and I will need to compile my single, personal C++ file over and over again as fast as possible, like how it is possible with the make
command in the sample
file of the repo.
I've been asking a few question about this here and made a little progress I commented and closed a few with but I still have not gotten it to work.
I want to include the mujoco library in my C++ script build with CMakeLists.txt. Other libraries are not this complicated. I can find_package
Torch and other libraries no problem and use everything in the library with my C++. Not so with MuJoCo.
MJAPI
@BenjaminNavarro @yuvaltassa
What is this?
How can I use this mujoco library in my project?
@MotorCityCobra this is only about trying to depend on MuJoCo's currently private, internal API, rather than functions that are meant to be user-facing.
To answer your question, to depend on MuJoCo in CMake, you should cmake --install
MuJoCo, then from your own project it's sufficient to just find_package(mujoco)
, then target_link_libraries(your_target mujoco::mujoco)
.
Maybe you could add a CMake option to export the private API or not? Default would be off of course to keep the current behavior but it would make it easy to just build and use MuJoCo as usual