From bc502f3b19099a97748cf6f91f2e213915d613c0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:24 +1100 Subject: [PATCH] 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. --- CMakeLists.txt | 25 ++++-- build_files/cmake/Modules/FindMoltenVK.cmake | 6 +- build_files/cmake/macros.cmake | 2 +- .../platform/platform_old_libs_update.cmake | 7 +- .../cmake/platform/platform_unix.cmake | 78 +++++++++++-------- source/creator/CMakeLists.txt | 11 ++- tests/CMakeLists.txt | 2 +- 7 files changed, 86 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2acae1d7b26..94bad8c20fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -399,6 +399,26 @@ mark_as_advanced(WITH_SYSTEM_GLOG) # Freestyle 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 if(WIN32 OR APPLE) 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) if(UNIX AND NOT APPLE) 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() option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON) diff --git a/build_files/cmake/Modules/FindMoltenVK.cmake b/build_files/cmake/Modules/FindMoltenVK.cmake index 07584e51ae5..aaaa6bcd87c 100644 --- a/build_files/cmake/Modules/FindMoltenVK.cmake +++ b/build_files/cmake/Modules/FindMoltenVK.cmake @@ -19,9 +19,13 @@ ENDIF() SET(_moltenvk_SEARCH_DIRS ${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 NAMES diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 44081ee5d81..dc7c101f91a 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1264,7 +1264,7 @@ endmacro() # Utility to gather and install precompiled shared libraries. macro(add_bundled_libraries library_dir) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) set(_library_dir ${LIBDIR}/${library_dir}) if(WIN32) file(GLOB _all_library_versions ${_library_dir}/*\.dll) diff --git a/build_files/cmake/platform/platform_old_libs_update.cmake b/build_files/cmake/platform/platform_old_libs_update.cmake index ab27dd89385..d71b5d45818 100644 --- a/build_files/cmake/platform/platform_old_libs_update.cmake +++ b/build_files/cmake/platform/platform_old_libs_update.cmake @@ -1,7 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-or-later # 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`. function(unset_cache_variables pattern) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 4f84fe262f5..1d8f264d8f1 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -4,38 +4,52 @@ # Libraries configuration for any *nix system including Linux and Unix (excluding APPLE). # 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. - set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228) +if(NOT WITH_LIBS_PRECOMPILED) + 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. - if(EXISTS ${LIBDIR_NATIVE_ABI}) - set(LIBDIR ${LIBDIR_NATIVE_ABI}) - 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() + # Path to precompiled libraries with known glibc 2.28 ABI. + set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228) + + # Choose the best suitable libraries. + if(EXISTS ${LIBDIR_NATIVE_ABI}) + set(LIBDIR ${LIBDIR_NATIVE_ABI}) 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() + + # Avoid namespace pollustion. + unset(LIBDIR_NATIVE_ABI) + unset(LIBDIR_GLIBC228_ABI) endif() - # Avoid namespace pollustion. - unset(LIBDIR_NATIVE_ABI) - unset(LIBDIR_GLIBC228_ABI) + if(NOT (EXISTS ${LIBDIR})) + message(STATUS + "Unable to find LIBDIR: ${LIBDIR}, system libraries may be used " + "(disable WITH_LIBS_PRECOMPILED to suppress this message)." + ) + unset(LIBDIR) + endif() endif() + # Support restoring this value once pre-compiled libraries have been handled. set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS}) -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}") file(GLOB LIB_SUBDIRS ${LIBDIR}/*) @@ -85,7 +99,7 @@ endmacro() # 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. -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) without_system_libs_begin() endif() @@ -114,7 +128,7 @@ endfunction() if(NOT WITH_SYSTEM_FREETYPE) # FreeType compiled with Brotli compression for woff2. find_package_wrapper(Freetype REQUIRED) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) find_package_wrapper(Brotli REQUIRED) # 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) # Installing into `site-packages`, warn when installing into `./../lib/` # which script authors almost certainly don't want. - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) path_is_prefix(LIBDIR PYTHON_SITE_PACKAGES _is_prefix) if(_is_prefix) message(WARNING " @@ -217,7 +231,7 @@ if(WITH_CODEC_SNDFILE) endif() if(WITH_CODEC_FFMPEG) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg) # Override FFMPEG components to also include static library dependencies # included with precompiled libraries, and to ensure correct link order. @@ -232,7 +246,7 @@ if(WITH_CODEC_FFMPEG) vpx x264 xvidcore) - if(EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a) + if((DEFINED LIBDIR) AND (EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a)) list(APPEND FFMPEG_FIND_COMPONENTS aom) endif() elseif(FFMPEG) @@ -469,7 +483,7 @@ if(WITH_OPENIMAGEDENOISE) endif() if(WITH_LLVM) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) set(LLVM_STATIC ON) endif() @@ -483,7 +497,7 @@ if(WITH_LLVM) endif() # 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")) list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY}) endif() @@ -539,7 +553,7 @@ if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING) endif() endif() -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) without_system_libs_end() 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. -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) # Clear the prefix path as it causes the `LIBDIR` to override system locations. unset(CMAKE_PREFIX_PATH) @@ -639,7 +653,7 @@ if(WITH_GHOST_WAYLAND) # 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. # 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) else() set(_use_system_wayland ON) @@ -703,7 +717,7 @@ if(WITH_GHOST_WAYLAND) add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR) 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") else() pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index fa3ab5d3b86..a0816f41724 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -605,7 +605,10 @@ if(UNIX AND NOT APPLE) ) 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( @@ -665,7 +668,7 @@ if(UNIX AND NOT APPLE) DESTINATION ${TARGETDIR_VER}/python/bin ) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) # Precompiled libraries, copy over complete lib directory. install_dir( ${PYTHON_LIBPATH} @@ -1499,7 +1502,7 @@ endif() # Always install USD shared library and datafiles regardless if Blender # 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 # relative to the location of the USD dll, if the dll does not exist # 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 # bundled Python module still needs it. -if(WITH_MATERIALX AND LIBDIR AND TARGETDIR_LIB) +if((DEFINED LIBDIR) AND TARGETDIR_LIB AND WITH_MATERIALX ) install( DIRECTORY ${LIBDIR}/materialx/libraries DESTINATION "${TARGETDIR_LIB}/materialx" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6dcfeecc654..ff3587d93c2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,7 +35,7 @@ endif() set(TEST_PYTHON_EXE_EXTRA_ARGS "") # 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) if(_is_prefix) # Keep the Python in Blender's SVN LIBDIR pristine, to avoid conflicts on updating.