Skip to content

Adding the ability to install libsimulate library and associated headers during installation.#2713

Merged
copybara-service[bot] merged 15 commits intogoogle-deepmind:mainfrom
vidurvij-apptronik:vidur/remove-installing-glfw3-headers
Sep 17, 2025
Merged

Adding the ability to install libsimulate library and associated headers during installation.#2713
copybara-service[bot] merged 15 commits intogoogle-deepmind:mainfrom
vidurvij-apptronik:vidur/remove-installing-glfw3-headers

Conversation

@vidurvij-apptronik
Copy link
Copy Markdown
Contributor

This is the second iteration of the code. I am updating cmake and depedncies file for simulate library to expose header files for simulate. This will allow us to directly use simulate library in mujoco and add our custom time stepping while using default visualizer similar to python.

@yuvaltassa
Copy link
Copy Markdown
Collaborator

cc @francesco-romano

Copy link
Copy Markdown
Contributor

@francesco-romano francesco-romano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did you test this CL? What is the test environment?

Comment on lines +135 to +138
platform_ui_adapter.h
glfw_adapter.h
glfw_dispatch.h
array_safety.h
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need all these headers to be public?

Also check also the target_link_libraries line. Now that we install the target we need to ensure its public dependencies are also available. Can they be moved to private?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do. If we want to use simulate. h and instantiate a Simulate object we need to call

 auto sim = std::make_unique<mj::Simulate>(
      std::make_unique<mj::GlfwAdapter>(),
      &cam, &opt, &pert, /* is_passive = */ false
  );

Which would need access to those headers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it

@vidurvij-apptronik
Copy link
Copy Markdown
Contributor Author

vidurvij-apptronik commented Jul 23, 2025

How did you test this CL? What is the test environment?

@francesco-romano I tested it using Ubuntu 20.04 and cmake. To test it, separately copied the file simulate/main.cc and compiled it using gcc with this command. This verifies that the simulate and mujoco are installed correctly.

LODEPNG_DIR=${HOME}/mujoco/build/lib; g++ -std=c++17 -I./build/_deps/lodepng-src/ main.cpp -o your_program -lmujoco -lsimulate -lglfw -lpthread -L${LODEPNG_DIR} -llodepng

@francesco-romano
Copy link
Copy Markdown
Contributor

How did you test this CL? What is the test environment?

@francesco-romano I tested it using Ubuntu 20.04 and cmake. To test it, separately copied the file simulate/main.cc and compiled it using gcc with this command. This verifies that the simulate and mujoco are installed correctly.

LODEPNG_DIR=${HOME}/mujoco/build/lib; g++ -std=c++17 -I./build/_deps/lodepng-src/ main.cpp -o your_program -lmujoco -lsimulate -lglfw -lpthread -L${LODEPNG_DIR} -llodepng

That is a bit brittle and not really indicative of the correct usage.

Can you test the following?

<get clean copy of mujoco with this change>
$ mkdir ~/test_install
$ mkdir -p mujoco/build
$ cd mujoco/build
$ cmake -DCMAKE_INSTALL_PREFIX=~/test_install ..
$ make -j4 && make install

Now you have the correctly installed mujoco and we need to source it for a new project.

$ mkdir ~/my_test_project
$ vim ~/my_test_project/CMakeLists.txt
...
somewhere do
find_package(mujoco)

add_executable(my_test main.cc)
target_link_libraries(my_test mujoco::libmujoco_simulate)
...

$ export PATH:~/test_install/bin:$PATH
$ mkdir ~/my_test_project/build
$ cd ~/my_test_project/build
$ cmake ..
$ make

Of course in main.cc use the libsimulate, I expect something like #include <mujoco/simulate.h>

target_compile_options(libsimulate PRIVATE ${MUJOCO_SIMULATE_COMPILE_OPTIONS})
target_link_libraries(libsimulate PUBLIC lodepng mujoco::platform_ui_adapter mujoco::mujoco)
target_link_options(libsimulate PRIVATE ${MUJOCO_SIMULATE_LINK_OPTIONS})
target_include_directories(libmujoco_simulate PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what about the <INSTALL_INTEFACE?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the install interface,

Comment on lines +135 to +138
platform_ui_adapter.h
glfw_adapter.h
glfw_dispatch.h
array_safety.h
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it

@vidurvij-apptronik
Copy link
Copy Markdown
Contributor Author

vidurvij-apptronik commented Aug 9, 2025

@francesco-romano Hey pushed the changes requested.

Following your request I was able to test it using

cmake_minimum_required(VERSION 3.16)
project(my_test)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Set the path to our installed MuJoCo
set(CMAKE_PREFIX_PATH "/Users/vidurvij/mujoco/test_install")

# Find MuJoCo package
find_package(mujoco REQUIRED)

# Find threads (required by simulate)
find_package(Threads REQUIRED)

# Create test executable
add_executable(my_test main.cc)
add_executable(my_simulate main_simulate.cc)

# Link against libmujoco_simulate as Francesco requested
target_link_libraries(my_test 
    mujoco::libmujoco_simulate
    mujoco::mujoco
    Threads::Threads
)

# On macOS, we need these frameworks
if(APPLE)
    find_package(OpenGL REQUIRED)
    target_link_libraries(my_test 
        OpenGL::GL
        "-framework Cocoa"
        "-framework CoreVideo"
    )
endif()

# Configure my_simulate executable
target_link_libraries(my_simulate
    mujoco::libmujoco_simulate
    mujoco::mujoco
    Threads::Threads
)

# Link GLFW directly from build directory
target_link_libraries(my_simulate /Users/vidurvij/mujoco/build/lib/libglfw3.a)

# Add GLFW include directory
target_include_directories(my_simulate PRIVATE /Users/vidurvij/mujoco/build/_deps/glfw3-src/include)

if(APPLE)
    target_link_libraries(my_simulate
        OpenGL::GL
        "-framework Cocoa"
        "-framework CoreVideo"
        "-framework IOKit"
    )
endif()

Also my executable were the main.cc in the simulate library and small script

#include <iostream>
#include <memory>


#include <simulate/simulate.h>
#include <simulate/platform_ui_adapter.h>
#include <mujoco/mujoco.h>

int main(int argc, char** argv) {
    std::cout << "Testing libmujoco_simulate installation..." << std::endl;
    
    std::cout << "MuJoCo version: " << mj_versionString() << std::endl;
    
    mujoco::Simulate* sim_ptr = nullptr;
    std::cout << "✓ mujoco::Simulate class is accessible" << std::endl;
    
    mujoco::PlatformUIAdapter* adapter_ptr = nullptr;
    std::cout << "✓ mujoco::PlatformUIAdapter class is accessible" << std::endl;
    
    const char* xml = R"(
        <mujoco>
            <worldbody>
                <light diffuse="1 1 1" pos="0 0 3" dir="0 0 -1"/>
                <body>
                    <geom type="sphere" size="0.1" rgba="1 0 0 1"/>
                </body>
            </worldbody>
        </mujoco>
    )";
    
    char error[1000] = {0};
    mjVFS vfs;
    mj_defaultVFS(&vfs);
    mj_addBufferVFS(&vfs, "model.xml", xml, strlen(xml));
    mjModel* model = mj_loadXML("model.xml", &vfs, error, sizeof(error));
    mj_deleteVFS(&vfs);
    
    if (model) {
        std::cout << "✓ Successfully created test model" << std::endl;
        mjData* data = mj_makeData(model);
        if (data) {
            std::cout << "✓ Successfully created mjData" << std::endl;
            
            mjvCamera cam;
            mjvOption opt;
            mjvPerturb pert;
            mjv_defaultCamera(&cam);
            mjv_defaultOption(&opt);
            mjv_defaultPerturb(&pert);
            
            try {
                auto sim = std::make_unique<mujoco::Simulate>(
                    nullptr,  // No UI adapter for this test
                    &cam,
                    &opt,
                    &pert,
                    true      // passive mode
                );
                std::cout << "✓ Successfully instantiated mujoco::Simulate" << std::endl;
            } catch (...) {
                std::cout << "Note: Simulate instantiation requires UI components" << std::endl;
            }
            
            mj_deleteData(data);
        }
        mj_deleteModel(model);
    } else {
        std::cerr << "Model creation failed: " << error << std::endl;
    }
    
    std::cout << "\n=== Test completed successfully ===" << std::endl;
    std::cout << "libmujoco_simulate is properly installed and usable!" << std::endl;
    
    return 0;
}

@francesco-romano
Copy link
Copy Markdown
Contributor

Thanks a lot. All good on my side

@yuvaltassa
Copy link
Copy Markdown
Collaborator

@vidurvij-apptronik you need to do the CLA thing please

@vidurvij-apptronik vidurvij-apptronik force-pushed the vidur/remove-installing-glfw3-headers branch from 9ccf28e to edb1790 Compare August 18, 2025 18:54
@yuvaltassa
Copy link
Copy Markdown
Collaborator

@vidurvij-apptronik do you understand where the breakage is coming from?

@vidurvij-apptronik
Copy link
Copy Markdown
Contributor Author

@yuvaltassa The python cmake was using the name libsimulate. We changed it to libmujoco_simulate. I have updated the name of the simulate library in python bindings cmake, it should be working now.

@yuvaltassa
Copy link
Copy Markdown
Collaborator

@yuvaltassa The python cmake was using the name libsimulate. We changed it to libmujoco_simulate. I have updated the name of the simulate library in python bindings cmake, it should be working now.

Nope

@francesco-romano
Copy link
Copy Markdown
Contributor

francesco-romano commented Aug 27, 2025

@yuvaltassa The python cmake was using the name libsimulate. We changed it to libmujoco_simulate. I have updated the name of the simulate library in python bindings cmake, it should be working now.

Nope

But the error is different

@vidurvij-apptronik

simulate/glfw_adapter.h:20:10: fatal error: GLFW/glfw3.h: No such file or directory

if glfw is not forwarded by simulate you might need to update the Bindings CMake to find it.

@vidurvij-apptronik
Copy link
Copy Markdown
Contributor Author

@yuvaltassa Can't figure out the issue with this pipeline. It seems it doesn't give any output.

@copybara-service copybara-service bot merged commit 9af1f55 into google-deepmind:main Sep 17, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants