Headless Blender Build With Non-Standard lib Location

Hello fellow blenderists, I hope your day is progressing smoothly.

I am trying to acquire a truly headless version of Blender 3.6 (one that has no dependencies on an installed XServer). Sadly I haven’t been able to find any compiled headless versions, so I’ve embarked on the ambitious and possibly foolhardy journey of trying to build it myself. I’ve encountered numerous obstacles along the way, some of which I’ve been able to solve and some which I have not, for which I would be very glad of any assistance.

My target system is CentOS 7, which natively does not support a modern enough version of make/cmake to compile, so I have the required build tools installed to a conda environment (which is probably where a lot of the problems are originating)

I update the headers location to include the conda env

export C_INCLUDE_PATH=/home/insico/anaconda3/envs/blender-build/include/:/usr/include
export CPLUS_INCLUDE_PATH=/home/insico/anaconda3/envs/blender-build/include/:/usr/include

I comment out the following line in /intern/cycles/kernel/CMakeLists.txt:

add_custom_command(
       OUTPUT ${cycles_kernel_oneapi_lib}
       COMMAND ${CMAKE_COMMAND} -E env
-              "LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
+#              "LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
               # `$ENV{PATH}` is for compiler to find `ld`.
               "PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}"
               ${SYCL_COMPILER}

To avoid a problem where some compiler warnings about float to double promotions stop compilation.

I am then able to proceed with the compilation up to Generating node_add_closure.oso, where I get stuck with the following message:

/home/insico/blender-git/lib/linux_x86_64_glibc_228/osl/bin/oslc: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
make[3]: *** [intern/cycles/kernel/osl/shaders/CMakeFiles/cycles_osl_shaders.dir/build.make:225: intern/cycles/kernel/osl/shaders/node_add_closure.oso] Error 127
make[2]: *** [CMakeFiles/Makefile2:3617: intern/cycles/kernel/osl/shaders/CMakeFiles/cycles_osl_shaders.dir/all] Error 2
make[1]: *** [Makefile:166: all] Error 2
make: *** [GNUmakefile:365: all] Error 2

Here I am stuck, for I cannot for the life of me get the build tools to recognise a non-standard library location. From googling I’ve tried the following to no avail:

  • Setting the LD_LIBRARY_PATH env variable (does nothing)
  • Setting the LIBRARY_PATH env variable (does nothing)
  • Setting the CMAKE_LIBRARY_PATH env variable (does nothing)
  • In CMakeLists.txt writing set(CMAKE_LIBRARY_PATH /home/insico/anaconda3/envs/blender-build/lib ${CMAKE_LIBRARY_PATH}) (does nothing)
  • In CMakeLists.txt writing link_directories(/home/insico/anaconda3/envs/blender-build/lib) (does nothing)

I am baffled that this is so hard to accomplish, so I can only assume I’m doing something drastically wrong and/or my knowledge of make/cmake is too poor to carry it out. Any help would be greatly appreciated.

Specs:
CentOS version = 7.9
Blender version = 3.6
make version = GNU Make 4.3
cmake version = 3.26.4
gcc version = (conda-forge gcc 13.1.0-0) 13.1.0
g++ version = (conda-forge gcc 13.1.0-0) 13.1.0

You can’t use the linux_x86_64_glibc_228 lib folder on centos7 as it ships with glibc 2.17 which as you have noticed does not enjoy the 2.28 binaries very much.

Hi @LazyDodo, thanks for your message!

My apologies I should have been more clear. It is not the Blender library folder than I’m having trouble with (although maybe I will further down the line), but rather the system library folder.

My updated build tools have libraries in /home/insico/anaconda3/envs/blender-build/lib, but cmake will only look for libraries in the default system locations (which are probably /lib/, /lib64, /usr/lib and /usr/lib64). What I’m looking for is a way to update the build process to look preferentially in my custom location, then the system locations second.

it is your problem, as is evident by the build error you are asking help with being oslc being run from it and it having an unhappy time. This folder has nothing for you, the binaries in this folder will never run on centos7 no matter how much you fudge the library paths.

The mere presence of that folder will make the blender build system favor it over anything else including system libs, to resolve at least the OSL issue you are running into right now:

  • Remove your /home/insico/blender-git/lib/linux_x86_64_glibc_228 folder (or move it out of the way)
  • cmake will generally cache locations of things it has found in the past, rather than recheck if they are still there, you’ll need to remove your current build folder and start fresh so CMake gets the opportunity to find the libs you have elsewhere.

You are correct of course that oslc is the build failure, but the error is in being unable to locate the system library libstdc++ because it’s in a non-standard location, rather than a version mismatch. If I place a symlink to my libstdc++ in /lib64 then things can progress further, although the build is ultimately doomed as you say due to the glibc mismatch :frowning:

I was hoping to find a way to use a custom library location without using the symlink hack, and even though it may be useless here, the answer would be useful for other projects if you happened to know how to achieve it?

How, for example, do people normally build on systems where they do not have root access to install the necessary build tools in the usual places?

normally you’d hint using LD_LIBRARY_PATH easiest way to see if that is working is likely something like

LD_LIBRARY_PATH=/lib64 /home/insico/blender-git/lib/linux_x86_64_glibc_228/osl/bin/oslc --help

Ah ok that’s very useful thanks. If I set LD_LIBRARY_PATH and call oslc directly I get the expected error about glibc:

/home/insico/blender-git/lib/linux_x86_64_glibc_228/osl/bin/oslc: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by /home/insico/blender-git/lib/linux_x86_64_glibc_228/boost/lib/libboost_filesystem.so.1.80.0)

Which is fine. If is export LD_LIBRARY_PATH and call make however I get a different error about finding the wrong version of libstdc++ (it finds the version in/lib64 not in my custom dir). I guess cmake prepends the normal library locations to LD_LIBRARY_PATH automatically or something, which normally makes sense except here it’s taking preference over the custom path, which is bad. Any idea how you could get cmake to not do that?

There seems to be a mistake in the code that drops the LD_LIBRARY_PATH value. Maybe this works?

diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index 6695411..0e00b85 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -1049,7 +1049,7 @@ if(PLATFORM_BUNDLED_LIBRARIES)
 
   # Environment variables to run precompiled executables that needed libraries.
   list(JOIN PLATFORM_BUNDLED_LIBRARY_DIRS ":" _library_paths)
-  set(PLATFORM_ENV_BUILD "LD_LIBRARY_PATH=\"${_library_paths}:${LD_LIBRARY_PATH}\"")
+  set(PLATFORM_ENV_BUILD "LD_LIBRARY_PATH=\"${_library_paths}:$LD_LIBRARY_PATH\"")
   set(PLATFORM_ENV_INSTALL "LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/lib/;$LD_LIBRARY_PATH")
   unset(_library_paths)
 endif()
` `

This is very much blender specific, (won’t work for any other cmake based projects), and so specific it will only work if our bundled libraries folder is used, but you can pass -DLD_LIBRARY_PATH=blahblah to cmake to to have it be appended to any commands it runs during the biuld, relevant code here.

That being said, I think I have spend enough time on getting things that have no hope in working to work and will politely bow out of further questions regarding this specific setup.

Edit:
seems like @brecht found the same code, i’m not entirely sure it’s a mistake though, it appears like it’s an escape hatch to supply an LD_LIBRARY_PATH though cmake, otherwise the if(DEFINED LD_LIBRARY_PATH) above it would make very little sense.

I don’t see if(DEFINED LD_LIBRARY_PATH) in the code?

Ah it seems Campbell added that yesterday, but it’s just hiding the issue:

Thanks @brecht that looks like it’s the right sort of thing, especially because it looks to be using the internally defined _library_paths before LD_LIBRARY_PATH, where as it would need to be the other way around for this to work.

I’ve tried the change and also swapping the ordering and no luck I’m afraid. I’ll try cleaning and rebuilding from scratch in case that makes a difference (sorry cmake is really not my strength).