CMake: add WITH_LIBS_PRECOMPILED option (UNIX only)

This makes it convenient to build blender without referencing
pre-compiled libraries which don't always work on newer Linux systems.

Previously I had to rename ../lib while creating the CMakeCache.txt
to ensure my systems libraries would be used.

This change ensures LIBDIR is undefined when WITH_LIBS_PRECOMPILED is
disabled, so any accidental use warns with CMake's `--warn-unused-vars`
argument is given.
This commit is contained in:
Campbell Barton 2023-01-19 17:07:24 +11:00
parent 66dee44088
commit bc502f3b19
7 changed files with 86 additions and 45 deletions

View File

@ -399,6 +399,26 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
# Freestyle # Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON) option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
# Libraries.
if(UNIX AND NOT APPLE)
# Optionally build without pre-compiled libraries.
# NOTE: this could be supported on all platforms however in practice UNIX is the only platform
# that has good support for detecting installed libraries.
option(WITH_LIBS_PRECOMPILED "\
Detect and link against pre-compiled libraries (typically found under \"../lib/\"). \
Disabling this option will use the system libraries although cached paths \
that point to pre-compiled libraries will be left as-is."
ON
)
mark_as_advanced(WITH_LIBS_PRECOMPILED)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
if(WITH_STATIC_LIBS)
option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF)
mark_as_advanced(WITH_BOOST_ICU)
endif()
endif()
# Misc # Misc
if(WIN32 OR APPLE) if(WIN32 OR APPLE)
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON) option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
@ -406,11 +426,6 @@ endif()
option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON) option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON) option(WITH_INSTALL_PORTABLE "Install redistributable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
if(WITH_STATIC_LIBS)
option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF)
mark_as_advanced(WITH_BOOST_ICU)
endif()
endif() endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON) option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)

View File

@ -19,9 +19,13 @@ ENDIF()
SET(_moltenvk_SEARCH_DIRS SET(_moltenvk_SEARCH_DIRS
${MOLTENVK_ROOT_DIR} ${MOLTENVK_ROOT_DIR}
${LIBDIR}/vulkan/MoltenVK
) )
# FIXME: These finder modules typically don't use LIBDIR,
# this should be set by `./build_files/cmake/platform/` instead.
IF(DEFINED LIBDIR)
SET(_moltenvk_SEARCH_DIRS ${_moltenvk_SEARCH_DIRS} ${LIBDIR}/vulkan/MoltenVK)
ENDIF()
FIND_PATH(MOLTENVK_INCLUDE_DIR FIND_PATH(MOLTENVK_INCLUDE_DIR
NAMES NAMES

View File

@ -1264,7 +1264,7 @@ endmacro()
# Utility to gather and install precompiled shared libraries. # Utility to gather and install precompiled shared libraries.
macro(add_bundled_libraries library_dir) macro(add_bundled_libraries library_dir)
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
set(_library_dir ${LIBDIR}/${library_dir}) set(_library_dir ${LIBDIR}/${library_dir})
if(WIN32) if(WIN32)
file(GLOB _all_library_versions ${_library_dir}/*\.dll) file(GLOB _all_library_versions ${_library_dir}/*\.dll)

View File

@ -1,7 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2022 Blender Foundation. All rights reserved. # Copyright 2022 Blender Foundation. All rights reserved.
# Auto update existing CMake caches for new libraries # Auto update existing CMake caches for new libraries.
# Assert that `LIBDIR` is defined.
if(NOT (DEFINED LIBDIR))
message(FATAL_ERROR "Logical error, expected 'LIBDIR' to be defined!")
endif()
# Clear cached variables whose name matches `pattern`. # Clear cached variables whose name matches `pattern`.
function(unset_cache_variables pattern) function(unset_cache_variables pattern)

View File

@ -4,38 +4,52 @@
# Libraries configuration for any *nix system including Linux and Unix (excluding APPLE). # Libraries configuration for any *nix system including Linux and Unix (excluding APPLE).
# Detect precompiled library directory # Detect precompiled library directory
if(NOT DEFINED LIBDIR)
# Path to a locally compiled libraries.
set(LIBDIR_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR})
string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME)
set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME})
# Path to precompiled libraries with known glibc 2.28 ABI. if(NOT WITH_LIBS_PRECOMPILED)
set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228) unset(LIBDIR)
else()
if(NOT DEFINED LIBDIR)
# Path to a locally compiled libraries.
set(LIBDIR_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR})
string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME)
set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME})
# Choose the best suitable libraries. # Path to precompiled libraries with known glibc 2.28 ABI.
if(EXISTS ${LIBDIR_NATIVE_ABI}) set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228)
set(LIBDIR ${LIBDIR_NATIVE_ABI})
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True) # Choose the best suitable libraries.
elseif(EXISTS ${LIBDIR_GLIBC228_ABI}) if(EXISTS ${LIBDIR_NATIVE_ABI})
set(LIBDIR ${LIBDIR_GLIBC228_ABI}) set(LIBDIR ${LIBDIR_NATIVE_ABI})
if(WITH_MEM_JEMALLOC)
# jemalloc provides malloc hooks.
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False)
else()
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True) set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
elseif(EXISTS ${LIBDIR_GLIBC228_ABI})
set(LIBDIR ${LIBDIR_GLIBC228_ABI})
if(WITH_MEM_JEMALLOC)
# jemalloc provides malloc hooks.
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False)
else()
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
endif()
endif() endif()
# Avoid namespace pollustion.
unset(LIBDIR_NATIVE_ABI)
unset(LIBDIR_GLIBC228_ABI)
endif() endif()
# Avoid namespace pollustion. if(NOT (EXISTS ${LIBDIR}))
unset(LIBDIR_NATIVE_ABI) message(STATUS
unset(LIBDIR_GLIBC228_ABI) "Unable to find LIBDIR: ${LIBDIR}, system libraries may be used "
"(disable WITH_LIBS_PRECOMPILED to suppress this message)."
)
unset(LIBDIR)
endif()
endif() endif()
# Support restoring this value once pre-compiled libraries have been handled. # Support restoring this value once pre-compiled libraries have been handled.
set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS}) set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS})
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}") message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
file(GLOB LIB_SUBDIRS ${LIBDIR}/*) file(GLOB LIB_SUBDIRS ${LIBDIR}/*)
@ -85,7 +99,7 @@ endmacro()
# These are libraries that may be precompiled. For this we disable searching in # These are libraries that may be precompiled. For this we disable searching in
# the system directories so that we don't accidentally use them instead. # the system directories so that we don't accidentally use them instead.
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
without_system_libs_begin() without_system_libs_begin()
endif() endif()
@ -114,7 +128,7 @@ endfunction()
if(NOT WITH_SYSTEM_FREETYPE) if(NOT WITH_SYSTEM_FREETYPE)
# FreeType compiled with Brotli compression for woff2. # FreeType compiled with Brotli compression for woff2.
find_package_wrapper(Freetype REQUIRED) find_package_wrapper(Freetype REQUIRED)
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
find_package_wrapper(Brotli REQUIRED) find_package_wrapper(Brotli REQUIRED)
# NOTE: This is done on WIN32 & APPLE but fails on some Linux systems. # NOTE: This is done on WIN32 & APPLE but fails on some Linux systems.
@ -141,7 +155,7 @@ if(WITH_PYTHON)
if(WITH_PYTHON_MODULE AND NOT WITH_INSTALL_PORTABLE) if(WITH_PYTHON_MODULE AND NOT WITH_INSTALL_PORTABLE)
# Installing into `site-packages`, warn when installing into `./../lib/` # Installing into `site-packages`, warn when installing into `./../lib/`
# which script authors almost certainly don't want. # which script authors almost certainly don't want.
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
path_is_prefix(LIBDIR PYTHON_SITE_PACKAGES _is_prefix) path_is_prefix(LIBDIR PYTHON_SITE_PACKAGES _is_prefix)
if(_is_prefix) if(_is_prefix)
message(WARNING " message(WARNING "
@ -217,7 +231,7 @@ if(WITH_CODEC_SNDFILE)
endif() endif()
if(WITH_CODEC_FFMPEG) if(WITH_CODEC_FFMPEG)
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg) set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg)
# Override FFMPEG components to also include static library dependencies # Override FFMPEG components to also include static library dependencies
# included with precompiled libraries, and to ensure correct link order. # included with precompiled libraries, and to ensure correct link order.
@ -232,7 +246,7 @@ if(WITH_CODEC_FFMPEG)
vpx vpx
x264 x264
xvidcore) xvidcore)
if(EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a) if((DEFINED LIBDIR) AND (EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a))
list(APPEND FFMPEG_FIND_COMPONENTS aom) list(APPEND FFMPEG_FIND_COMPONENTS aom)
endif() endif()
elseif(FFMPEG) elseif(FFMPEG)
@ -469,7 +483,7 @@ if(WITH_OPENIMAGEDENOISE)
endif() endif()
if(WITH_LLVM) if(WITH_LLVM)
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
set(LLVM_STATIC ON) set(LLVM_STATIC ON)
endif() endif()
@ -483,7 +497,7 @@ if(WITH_LLVM)
endif() endif()
# Symbol conflicts with same UTF library used by OpenCollada # Symbol conflicts with same UTF library used by OpenCollada
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
if(WITH_OPENCOLLADA AND (${LLVM_VERSION} VERSION_LESS "4.0.0")) if(WITH_OPENCOLLADA AND (${LLVM_VERSION} VERSION_LESS "4.0.0"))
list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY}) list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY})
endif() endif()
@ -539,7 +553,7 @@ if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING)
endif() endif()
endif() endif()
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
without_system_libs_end() without_system_libs_end()
endif() endif()
@ -583,7 +597,7 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
# #
# Keep last, so indirectly linked libraries don't override our own pre-compiled libs. # Keep last, so indirectly linked libraries don't override our own pre-compiled libs.
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
# Clear the prefix path as it causes the `LIBDIR` to override system locations. # Clear the prefix path as it causes the `LIBDIR` to override system locations.
unset(CMAKE_PREFIX_PATH) unset(CMAKE_PREFIX_PATH)
@ -639,7 +653,7 @@ if(WITH_GHOST_WAYLAND)
# When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present, # When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present,
# there is no need to search for the libraries as they are not needed for building. # there is no need to search for the libraries as they are not needed for building.
# Only the headers are needed which can reference the known paths. # Only the headers are needed which can reference the known paths.
if(EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD) if((DEFINED LIBDIR) AND (EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD))
set(_use_system_wayland OFF) set(_use_system_wayland OFF)
else() else()
set(_use_system_wayland ON) set(_use_system_wayland ON)
@ -703,7 +717,7 @@ if(WITH_GHOST_WAYLAND)
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR) add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
endif() endif()
if(EXISTS "${LIBDIR}/wayland/bin/wayland-scanner") if((DEFINED LIBDIR) AND (EXISTS "${LIBDIR}/wayland/bin/wayland-scanner"))
set(WAYLAND_SCANNER "${LIBDIR}/wayland/bin/wayland-scanner") set(WAYLAND_SCANNER "${LIBDIR}/wayland/bin/wayland-scanner")
else() else()
pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)

View File

@ -605,7 +605,10 @@ if(UNIX AND NOT APPLE)
) )
endif() endif()
if(EXISTS ${LIBDIR}/mesa) # NOTE: there is a bug in CMake 3.25.1 where `LIBDIR` is reported as undefined.
if(NOT DEFINED LIBDIR)
# Pass.
elseif(EXISTS ${LIBDIR}/mesa)
install(DIRECTORY ${LIBDIR}/mesa/lib/ DESTINATION "lib/mesa/") install(DIRECTORY ${LIBDIR}/mesa/lib/ DESTINATION "lib/mesa/")
install( install(
@ -665,7 +668,7 @@ if(UNIX AND NOT APPLE)
DESTINATION ${TARGETDIR_VER}/python/bin DESTINATION ${TARGETDIR_VER}/python/bin
) )
if(EXISTS ${LIBDIR}) if(DEFINED LIBDIR)
# Precompiled libraries, copy over complete lib directory. # Precompiled libraries, copy over complete lib directory.
install_dir( install_dir(
${PYTHON_LIBPATH} ${PYTHON_LIBPATH}
@ -1499,7 +1502,7 @@ endif()
# Always install USD shared library and datafiles regardless if Blender # Always install USD shared library and datafiles regardless if Blender
# itself uses them, the bundled Python module still needs it. # itself uses them, the bundled Python module still needs it.
if(LIBDIR AND TARGETDIR_LIB) if((DEFINED LIBDIR) AND TARGETDIR_LIB)
# On windows the usd library sits in ./blender.shared copy the files # On windows the usd library sits in ./blender.shared copy the files
# relative to the location of the USD dll, if the dll does not exist # relative to the location of the USD dll, if the dll does not exist
# assume we are linking against the static 3.5 lib. # assume we are linking against the static 3.5 lib.
@ -1556,7 +1559,7 @@ endif()
# Always install MaterialX files regardless if Blender itself uses them, the # Always install MaterialX files regardless if Blender itself uses them, the
# bundled Python module still needs it. # bundled Python module still needs it.
if(WITH_MATERIALX AND LIBDIR AND TARGETDIR_LIB) if((DEFINED LIBDIR) AND TARGETDIR_LIB AND WITH_MATERIALX )
install( install(
DIRECTORY ${LIBDIR}/materialx/libraries DIRECTORY ${LIBDIR}/materialx/libraries
DESTINATION "${TARGETDIR_LIB}/materialx" DESTINATION "${TARGETDIR_LIB}/materialx"

View File

@ -35,7 +35,7 @@ endif()
set(TEST_PYTHON_EXE_EXTRA_ARGS "") set(TEST_PYTHON_EXE_EXTRA_ARGS "")
# Check if this a Blender managed Python installation, if so, don't add `*.pyc` files. # Check if this a Blender managed Python installation, if so, don't add `*.pyc` files.
if(LIBDIR) if(DEFINED LIBDIR)
path_is_prefix(LIBDIR TEST_PYTHON_EXE _is_prefix) path_is_prefix(LIBDIR TEST_PYTHON_EXE _is_prefix)
if(_is_prefix) if(_is_prefix)
# Keep the Python in Blender's SVN LIBDIR pristine, to avoid conflicts on updating. # Keep the Python in Blender's SVN LIBDIR pristine, to avoid conflicts on updating.