Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ option(NBL_STATIC_BUILD "" OFF) # ON for static builds, OFF for shared
option(NBL_COMPILER_DYNAMIC_RUNTIME "" ON)
option(NBL_SANITIZE_ADDRESS OFF)
option(NBL_DEBUG_RTC_ENABLED "Enable Runtime Checks for Debug builds" OFF)
option(NBL_USE_CONAN "Use Conan to fetch dependencies" ON)

set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT $<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>) # ignored on non xMSVC-ABI targets

Expand All @@ -62,6 +63,10 @@ else()
endif()
endif()

if (NBL_USE_CONAN)
include(cmake/conan.cmake)
endif()

find_package(Vulkan)
if (Vulkan_FOUND)
message(STATUS "Found Vulkan SDK")
Expand Down
186 changes: 186 additions & 0 deletions cmake/conan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Check if Conan is present in the system
find_program(CONAN_EXECUTABLE conan)
if (NOT CONAN_EXECUTABLE)
# Conan is not found, install it using PIP
find_program(PIP_EXECUTABLE pip)
if (NOT PIP_EXECUTABLE)
message(FATAL_ERROR "Pip executable not found. Please install python and add it to PATH to proceed with Conan installation.")
endif()

# Install conan using pip
execute_process(
COMMAND ${PIP_EXECUTABLE} install conan
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE pip_result
)

if (NOT pip_result EQUAL "0")
message(FATAL_ERROR "Failed to install Conan using pip. Please check your Python and pip installation.")
endif()

# After installation, try to find Conan again
find_program(CONAN_EXECUTABLE conan)
if (NOT CONAN_EXECUTABLE)
message(FATAL_ERROR "Conan executable not found. Please ensure Conan is in your PATH.")
endif()
endif()

# Determine the Conan compiler name based on the CMake compiler ID
if (NOT CONAN_COMPILER)
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
set(CONAN_COMPILER "apple-clang")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CONAN_COMPILER "clang")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CONAN_COMPILER "msvc")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CONAN_COMPILER "gcc")
endif()
endif()

# Extract the major version number from the CMake compiler version
if (NOT CONAN_COMPILER_VERSION)
if (CONAN_COMPILER STREQUAL "msvc")
message (STATUS "Detected MSVC version: ${CMAKE_CXX_COMPILER_VERSION}")

# special handling for msvc to extract the major version (e.g., 143 from 14.3.0)
string (REGEX MATCH "^[0-9]+\\.[0-9]" MSVC_VERSION_MATCH ${CMAKE_CXX_COMPILER_VERSION})

# remove the dot to get the major version (e.g., 143 from 14.3)
string (REPLACE "." "" CONAN_COMPILER_VERSION ${MSVC_VERSION_MATCH})
else()
string(REGEX MATCH "^[0-9]+" CONAN_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION})
endif()
endif()

# Map Architectures to Conan's expected values
if (NOT CONAN_ARCH)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
set(CONAN_ARCH "x86_64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686")
set(CONAN_ARCH "x86")
else ()
message(WARNING "Unknown architecture ${CMAKE_SYSTEM_PROCESSOR}, using it directly for Conan")
set(CONAN_ARCH ${CMAKE_SYSTEM_PROCESSOR})
endif()
endif()

# Map CXX_STANDARD to Conan's expected value
if (NOT CONAN_CXX_STANDARD)
if (CMAKE_CXX_STANDARD)
set(CONAN_CXX_STANDARD ${CMAKE_CXX_STANDARD})
else()
message(WARNING "CMAKE_CXX_STANDARD is not set, defaulting to C++20 for Conan profile")
set(CONAN_CXX_STANDARD 20) # Default to C++17 if not specified
endif()
endif()

# Determine OS-specific Conan settings
if(WIN32)
set(CONAN_OS_SPECIFIC "compiler.runtime=dynamic")

# Append runtime version for Clang-cl
if(MSVC_TOOLSET_VERSION AND NOT CONAN_COMPILER STREQUAL "msvc")
set (CONAN_OS_SPECIFIC "${CONAN_OS_SPECIFIC}\ncompiler.runtime_version=v${MSVC_TOOLSET_VERSION}")
endif()

elseif(APPLE)
# macOS always uses LLVM's libc++
set(CONAN_OS_SPECIFIC "compiler.libcxx=libc++")

elseif(UNIX)
# On Linux, determine if Clang was forced to use libc++, otherwise default to libstdc++11
set(CONAN_LIBCXX "libstdc++11")

if(CONAN_COMPILER STREQUAL "clang")
# Check if the developer passed -stdlib=libc++ in the CMake cache or env
if(CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+")
set(CONAN_LIBCXX "libc++")
endif()
endif()

set(CONAN_OS_SPECIFIC "compiler.libcxx=${CONAN_LIBCXX}")
endif()

# Set the Conan profile content
set(CONAN_PROFILE_PATH "${CMAKE_BINARY_DIR}/conan_profile.txt")
set(CONAN_PROFILE "[settings]
os=${CMAKE_SYSTEM_NAME}
arch=${CONAN_ARCH}
compiler=${CONAN_COMPILER}
compiler.version=${CONAN_COMPILER_VERSION}
compiler.cppstd=${CONAN_CXX_STANDARD}
${CONAN_OS_SPECIFIC}

[conf]
tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}
")

# Make a message with file contents
message(STATUS "Generating Conan profile at ${CONAN_PROFILE_PATH}...")
message(STATUS "Conan profile content:\n${CONAN_PROFILE}")

file(WRITE ${CONAN_PROFILE_PATH} ${CONAN_PROFILE})

if (CMAKE_GENERATOR MATCHES "Ninja Multi-Config" OR CMAKE_GENERATOR MATCHES "Visual Studio")
if (CMAKE_CONFIGURATION_TYPES)
set(CONAN_CONFIGS ${CMAKE_CONFIGURATION_TYPES})
# remove MinSizeRel if it exists, and map it to Release

else()
set(CONAN_CONFIGS "Debug;Release;RelWithDebInfo")
endif()

list(REMOVE_ITEM CONAN_CONFIGS "MinSizeRel")
else()
if(NOT CMAKE_BUILD_TYPE)
message(WARNING "CMAKE_BUILD_TYPE is not set, defaulting to Release for Conan.")
set(CMAKE_BUILD_TYPE "Release")
endif()
set(CONAN_CONFIGS ${CMAKE_BUILD_TYPE})
endif()

set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL "Release" CACHE STRING "Fallback to Release dependencies for MinSizeRel" FORCE)

# Run Conan install for each configuration
foreach(CONFIG IN LISTS CONAN_CONFIGS)
message(STATUS "Running Conan install for build type: ${CONFIG}...")

# Pass build_type dynamically
set(CONAN_CLI_ARGS
"-s:h" "build_type=${CONFIG}"
"-s:b" "build_type=Release"
)

# Inject MSVC runtime type dynamically for Windows
if(WIN32)
if(CONFIG STREQUAL "Debug")
set(MSVC_RUNTIME_TYPE "Debug")
else()
set(MSVC_RUNTIME_TYPE "Release")
endif()

list(APPEND CONAN_CLI_ARGS
"-s:h" "compiler.runtime_type=${MSVC_RUNTIME_TYPE}"
"-s:b" "compiler.runtime_type=Release"
)
endif()

execute_process(
COMMAND ${CONAN_EXECUTABLE} install ${CMAKE_SOURCE_DIR}
--profile:all ${CONAN_PROFILE_PATH}
${CONAN_CLI_ARGS}
--build=missing
-cc core.graph:compatibility_mode=optimized
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE conan_result
)

if(NOT conan_result EQUAL "0")
message(FATAL_ERROR "Conan install failed for configuration: ${CONFIG}!")
endif()
endforeach()

if(NOT conan_result EQUAL "0")
message(FATAL_ERROR "Conan install failed!")
endif()
26 changes: 26 additions & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import json
from conan import ConanFile
from conan.tools.cmake import cmake_layout, CMakeToolchain, CMakeConfigDeps

class VeritasProject(ConanFile):
settings = "os", "compiler", "build_type", "arch"

default_options = {
"libyuv/*:with_jpeg":False,
"dav1d/*:with_tools":False
}

def requirements(self):
self.requires("libavif/1.4.1")

def layout(self):
cmake_layout(self)

def generate(self):
deps = CMakeConfigDeps(self)
deps.generate()

tc = CMakeToolchain(self)
# Redirect Conan's preset output so CMake doesn't load it as the default User file
tc.user_presets_path = ""
tc.generate()
2 changes: 2 additions & 0 deletions include/nbl/config/BuildConfigOptions.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#cmakedefine _NBL_COMPILE_WITH_BAW_LOADER_
#cmakedefine _NBL_COMPILE_WITH_JPG_LOADER_
#cmakedefine _NBL_COMPILE_WITH_PNG_LOADER_
#cmakedefine _NBL_COMPILE_WITH_AVIF_LOADER_
#cmakedefine _NBL_COMPILE_WITH_TGA_LOADER_
#ifdef _NBL_COMPILE_WITH_OPEN_EXR_ // ? TODO
#cmakedefine _NBL_COMPILE_WITH_OPENEXR_LOADER_
Expand All @@ -41,6 +42,7 @@
#cmakedefine _NBL_COMPILE_WITH_TGA_WRITER_
#cmakedefine _NBL_COMPILE_WITH_JPG_WRITER_
#cmakedefine _NBL_COMPILE_WITH_PNG_WRITER_
#cmakedefine _NBL_COMPILE_WITH_AVIF_WRITER_
#ifdef _NBL_COMPILE_WITH_OPEN_EXR_ // ? TODO
#cmakedefine _NBL_COMPILE_WITH_OPENEXR_WRITER_
#endif
Expand Down
20 changes: 20 additions & 0 deletions src/nbl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,20 @@ if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${NBL_ROOT_PATH}/install/${PLATFORM}" CACHE PATH "Install path" FORCE)
endif()

if (NBL_USE_CONAN)
# convert to lowercase
if (CMAKE_GENERATOR MATCHES "Visual Studio" OR CMAKE_GENERATOR MATCHES "Ninja Multi-Config")
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/build/generators")
else()
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/generators")
endif()
endif()

# include utility macros/functions
include(common)

find_package(libavif CONFIG REQUIRED)

#[[ Loaders and writers compile options available to edit by user
All revelant _NBL_COMPILE_WITH will be there]]
option(_NBL_COMPILE_WITH_MTL_LOADER_ "Compile with MTL Loader" OFF) #default off until Material Compiler 2
Expand All @@ -60,6 +71,8 @@ option(_NBL_COMPILE_WITH_JPG_LOADER_ "Compile with JPG Loader" ON)
option(_NBL_COMPILE_WITH_JPG_WRITER_ "Compile with JPG Writer" ON)
option(_NBL_COMPILE_WITH_PNG_LOADER_ "Compile with PNG Loader" ON)
option(_NBL_COMPILE_WITH_PNG_WRITER_ "Compile with PNG Writer" ON)
option(_NBL_COMPILE_WITH_AVIF_LOADER_ "Compile with AVIF Loader" ON)
option(_NBL_COMPILE_WITH_AVIF_WRITER_ "Compile with AVIF Writer" ON)
option(_NBL_COMPILE_WITH_TGA_LOADER_ "Compile with TGA Loader" ON)
option(_NBL_COMPILE_WITH_TGA_WRITER_ "Compile with TGA Writer" ON)
option(_NBL_COMPILE_WITH_OPENEXR_LOADER_ "Compile with OpenEXR Loader" ON)
Expand Down Expand Up @@ -214,6 +227,7 @@ set(NBL_ASSET_SOURCES

# Image loaders
asset/interchange/IImageLoader.cpp
asset/interchange/CImageLoaderAVIF.cpp
asset/interchange/CImageLoaderJPG.cpp
asset/interchange/CImageLoaderPNG.cpp
asset/interchange/CImageLoaderTGA.cpp
Expand Down Expand Up @@ -575,6 +589,12 @@ else()
endif()
list(APPEND PUBLIC_BUILD_INCLUDE_DIRS ${THIRD_PARTY_SOURCE_DIR}/libpng)

# libavif
if (NBL_STATIC_BUILD)
target_link_libraries(Nabla INTERFACE avif)
else()
target_link_libraries(Nabla PRIVATE avif)
endif()

# OpenEXR
if (_NBL_COMPILE_WITH_OPEN_EXR_)
Expand Down
7 changes: 7 additions & 0 deletions src/nbl/asset/IAssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#include "nbl/asset/interchange/CImageLoaderJPG.h"
#endif

#ifdef _NBL_COMPILE_WITH_AVIF_LOADER_
#include "nbl/asset/interchange/CImageLoaderAVIF.h"
#endif

#ifdef _NBL_COMPILE_WITH_PNG_LOADER_
#include "nbl/asset/interchange/CImageLoaderPNG.h"
#endif
Expand Down Expand Up @@ -143,6 +147,9 @@ void IAssetManager::addLoadersAndWriters()
#ifdef _NBL_COMPILE_WITH_PNG_LOADER_
addAssetLoader(core::make_smart_refctd_ptr<asset::CImageLoaderPng>());
#endif
#ifdef _NBL_COMPILE_WITH_AVIF_LOADER_
addAssetLoader(core::make_smart_refctd_ptr<asset::CImageLoaderAVIF>());
#endif
#ifdef _NBL_COMPILE_WITH_OPENEXR_LOADER_
addAssetLoader(core::make_smart_refctd_ptr<asset::CImageLoaderOpenEXR>(this));
#endif
Expand Down
Loading
Loading