From 3d97355fc7344498318f42635412855dabb13d22 Mon Sep 17 00:00:00 2001 From: N'yoma Diamond Date: Wed, 5 Aug 2026 16:32:50 +0100 Subject: [PATCH 1/5] Gate PUBLIC compiler-specific flags by consumer compiler ID Fixes cross-compiler linking (e.g. MSVC-built dlib consumed by clang++) where PUBLIC flags like /bigobj were unconditionally forced onto every downstream consumer regardless of which compiler it used. Splits the shared active_compile_opts list into active_compile_opts_gcc_public and active_compile_opts_msvc_public, and forwards each bucket to consumers only via a COMPILE_LANG_AND_ID generator expression matching their own compiler. MSVC consumers still get /bigobj automatically; non-MSVC consumers no longer receive it. See https://github.com/davisking/dlib/issues/3125 and https://github.com/davisking/dlib/pull/3126. Co-Authored-By: Claude Sonnet 5 --- dlib/CMakeLists.txt | 8 +++-- .../set_compiler_specific_options.cmake | 35 +++++++++++-------- dlib/cmake_utils/test_for_avx/CMakeLists.txt | 5 +-- dlib/cmake_utils/test_for_sse4/CMakeLists.txt | 5 +-- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/dlib/CMakeLists.txt b/dlib/CMakeLists.txt index 04b5d92059..9c2304550b 100644 --- a/dlib/CMakeLists.txt +++ b/dlib/CMakeLists.txt @@ -807,10 +807,14 @@ if (NOT TARGET dlib) target_compile_features(dlib PUBLIC cxx_std_14) if((MSVC AND CMAKE_VERSION VERSION_LESS 3.11)) - target_compile_options(dlib PUBLIC ${active_compile_opts}) + # Old CMake/VS generators can't evaluate the generator expressions below. + target_compile_options(dlib PUBLIC ${active_compile_opts_gcc_public} ${active_compile_opts_msvc_public}) target_compile_options(dlib PRIVATE ${active_compile_opts_private}) else() - target_compile_options(dlib PUBLIC $<$:${active_compile_opts}>) + # Only forward each bucket of flags to consumers using a matching + # compiler (see https://github.com/davisking/dlib/issues/3125). + target_compile_options(dlib PUBLIC $<$:${active_compile_opts_gcc_public}>) + target_compile_options(dlib PUBLIC $<$:${active_compile_opts_msvc_public}>) target_compile_options(dlib PRIVATE $<$:${active_compile_opts_private}>) endif() diff --git a/dlib/cmake_utils/set_compiler_specific_options.cmake b/dlib/cmake_utils/set_compiler_specific_options.cmake index 6e2682da08..e9dfa262e9 100644 --- a/dlib/cmake_utils/set_compiler_specific_options.cmake +++ b/dlib/cmake_utils/set_compiler_specific_options.cmake @@ -26,23 +26,28 @@ set(gcc_like_compilers GNU Clang Intel) set(intel_archs x86_64 i386 i686 AMD64 amd64 x86) -# Setup some options to allow a user to enable SSE and AVX instruction use. +# Setup some options to allow a user to enable SSE and AVX instruction use. +# +# NOTE: public flags go into active_compile_opts_gcc_public or +# active_compile_opts_msvc_public (instead of one shared list) so that +# dlib/CMakeLists.txt can forward each bucket only to consumers using a +# matching compiler. See https://github.com/davisking/dlib/issues/3125. if ((";${gcc_like_compilers};" MATCHES ";${CMAKE_CXX_COMPILER_ID};") AND (";${intel_archs};" MATCHES ";${CMAKE_SYSTEM_PROCESSOR};") AND NOT USE_AUTO_VECTOR) option(USE_SSE2_INSTRUCTIONS "Compile your program with SSE2 instructions" OFF) option(USE_SSE4_INSTRUCTIONS "Compile your program with SSE4 instructions" OFF) option(USE_AVX_INSTRUCTIONS "Compile your program with AVX instructions" OFF) if(USE_AVX_INSTRUCTIONS) - list(APPEND active_compile_opts -mavx) + list(APPEND active_compile_opts_gcc_public -mavx) message(STATUS "Enabling AVX instructions") elseif (USE_SSE4_INSTRUCTIONS) - list(APPEND active_compile_opts -msse4) + list(APPEND active_compile_opts_gcc_public -msse4) message(STATUS "Enabling SSE4 instructions") elseif(USE_SSE2_INSTRUCTIONS) - list(APPEND active_compile_opts -msse2) + list(APPEND active_compile_opts_gcc_public -msse2) message(STATUS "Enabling SSE2 instructions") endif() -elseif (MSVC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # else if using Visual Studio +elseif (MSVC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # else if using Visual Studio # Use SSE2 by default when using Visual Studio. option(USE_SSE2_INSTRUCTIONS "Compile your program with SSE2 instructions" ON) option(USE_SSE4_INSTRUCTIONS "Compile your program with SSE4 instructions" OFF) @@ -51,13 +56,13 @@ elseif (MSVC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # else if using Visu include(CheckTypeSize) check_type_size( "void*" SIZE_OF_VOID_PTR) if(USE_AVX_INSTRUCTIONS) - list(APPEND active_compile_opts /arch:AVX) + list(APPEND active_compile_opts_msvc_public /arch:AVX) message(STATUS "Enabling AVX instructions") elseif (USE_SSE4_INSTRUCTIONS) # Visual studio doesn't have an /arch:SSE2 flag when building in 64 bit modes. # So only give it when we are doing a 32 bit build. if (SIZE_OF_VOID_PTR EQUAL 4) - list(APPEND active_compile_opts /arch:SSE2) + list(APPEND active_compile_opts_msvc_public /arch:SSE2) endif() message(STATUS "Enabling SSE4 instructions") list(APPEND active_preprocessor_switches "-DDLIB_HAVE_SSE2") @@ -67,7 +72,7 @@ elseif (MSVC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # else if using Visu # Visual studio doesn't have an /arch:SSE2 flag when building in 64 bit modes. # So only give it when we are doing a 32 bit build. if (SIZE_OF_VOID_PTR EQUAL 4) - list(APPEND active_compile_opts /arch:SSE2) + list(APPEND active_compile_opts_msvc_public /arch:SSE2) endif() message(STATUS "Enabling SSE2 instructions") list(APPEND active_preprocessor_switches "-DDLIB_HAVE_SSE2") @@ -77,7 +82,7 @@ elseif((";${gcc_like_compilers};" MATCHES ";${CMAKE_CXX_COMPILER_ID};") AND ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "^arm")) option(USE_NEON_INSTRUCTIONS "Compile your program with ARM-NEON instructions" OFF) if(USE_NEON_INSTRUCTIONS) - list(APPEND active_compile_opts -mfpu=neon) + list(APPEND active_compile_opts_gcc_public -mfpu=neon) message(STATUS "Enabling ARM-NEON instructions") endif() endif() @@ -89,13 +94,13 @@ if (CMAKE_COMPILER_IS_GNUCXX) # By default, g++ won't warn or error if you forget to return a value in a # function which requires you to do so. This option makes it give a warning # for doing this. - list(APPEND active_compile_opts "-Wreturn-type") + list(APPEND active_compile_opts_gcc_public "-Wreturn-type") endif() if ("Clang" MATCHES ${CMAKE_CXX_COMPILER_ID} AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) # Clang 6 had a default template recursion depth of 256. This was changed to 1024 in Clang 7. # It must be increased on Clang 6 and below to ensure that the dnn examples don't error out. - list(APPEND active_compile_opts "-ftemplate-depth=500") + list(APPEND active_compile_opts_gcc_public "-ftemplate-depth=500") endif() if (MSVC) @@ -103,17 +108,17 @@ if (MSVC) # However, code generated by file_to_code_ex and code using DNN module can have # them. So this flag enables > 65k sections, but produces .obj files # that will not be readable by VS 2005. - list(APPEND active_compile_opts "/bigobj") + list(APPEND active_compile_opts_msvc_public "/bigobj") # Build dlib with all cores. Don't propagate the setting to client programs # though since they might compile large translation units that use too much # RAM. list(APPEND active_compile_opts_private "/MP") - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.3) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.3) # Clang can compile all Dlib's code at Windows platform. Tested with Clang 5 - list(APPEND active_compile_opts -Xclang) - list(APPEND active_compile_opts -fcxx-exceptions) + list(APPEND active_compile_opts_msvc_public -Xclang) + list(APPEND active_compile_opts_msvc_public -fcxx-exceptions) endif() endif() diff --git a/dlib/cmake_utils/test_for_avx/CMakeLists.txt b/dlib/cmake_utils/test_for_avx/CMakeLists.txt index 44363bc5ec..0367b1058f 100644 --- a/dlib/cmake_utils/test_for_avx/CMakeLists.txt +++ b/dlib/cmake_utils/test_for_avx/CMakeLists.txt @@ -4,12 +4,13 @@ project(avx_test) set(USE_AVX_INSTRUCTIONS ON CACHE BOOL "Use AVX instructions") -# Pull this in since it sets the AVX compile options by putting that kind of stuff into the active_compile_opts list. +# Pull this in since it sets the AVX compile options by putting that kind of stuff into the +# active_compile_opts_gcc_public / active_compile_opts_msvc_public lists. include(../set_compiler_specific_options.cmake) try_run(run_result compile_result ${PROJECT_BINARY_DIR}/avx_test_try_run_build ${CMAKE_CURRENT_LIST_DIR}/avx_test.cpp - COMPILE_DEFINITIONS ${active_compile_opts}) + COMPILE_DEFINITIONS ${active_compile_opts_gcc_public} ${active_compile_opts_msvc_public}) message(STATUS "run_result = ${run_result}") message(STATUS "compile_result = ${compile_result}") diff --git a/dlib/cmake_utils/test_for_sse4/CMakeLists.txt b/dlib/cmake_utils/test_for_sse4/CMakeLists.txt index 6d3a5b372b..0da5d7fd3d 100644 --- a/dlib/cmake_utils/test_for_sse4/CMakeLists.txt +++ b/dlib/cmake_utils/test_for_sse4/CMakeLists.txt @@ -4,12 +4,13 @@ project(sse4_test) set(USE_SSE4_INSTRUCTIONS ON CACHE BOOL "Use SSE4 instructions") -# Pull this in since it sets the SSE4 compile options by putting that kind of stuff into the active_compile_opts list. +# Pull this in since it sets the SSE4 compile options by putting that kind of stuff into the +# active_compile_opts_gcc_public / active_compile_opts_msvc_public lists. include(../set_compiler_specific_options.cmake) try_run(run_result compile_result ${PROJECT_BINARY_DIR}/sse4_test_try_run_build ${CMAKE_CURRENT_LIST_DIR}/sse4_test.cpp - COMPILE_DEFINITIONS ${active_compile_opts}) + COMPILE_DEFINITIONS ${active_compile_opts_gcc_public} ${active_compile_opts_msvc_public}) message(STATUS "run_result = ${run_result}") message(STATUS "compile_result = ${compile_result}") From 869cd309d3af3fefb92496756e0e9a5608bb169b Mon Sep 17 00:00:00 2001 From: Davis King Date: Sun, 9 Aug 2026 17:53:07 -0400 Subject: [PATCH 2/5] Handle compiler frontends and SIMD options in installed packages Select compiler-specific options when the installed package is consumed instead of exporting options for the compiler that built dlib. This preserves /bigobj for MSVC and clang-cl, avoids passing it to clang++, and translates configured SIMD options to the consumer's frontend. Add regression coverage for installed packages using MSVC, clang++, and clang-cl. --- .github/workflows/build_cpp.yml | 16 +++++ dlib/CMakeLists.txt | 17 ++--- dlib/cmake_utils/dlibConfig.cmake.in | 72 +++++++++++++++++-- .../set_compiler_specific_options.cmake | 38 +++++----- dlib/cmake_utils/test_for_avx/CMakeLists.txt | 5 +- .../test_for_dlib_config/CMakeLists.txt | 37 ++++++++++ .../test_for_dlib_config/dlib_config_test.cpp | 10 +++ dlib/cmake_utils/test_for_sse4/CMakeLists.txt | 5 +- 8 files changed, 161 insertions(+), 39 deletions(-) create mode 100644 dlib/cmake_utils/test_for_dlib_config/CMakeLists.txt create mode 100644 dlib/cmake_utils/test_for_dlib_config/dlib_config_test.cpp diff --git a/.github/workflows/build_cpp.yml b/.github/workflows/build_cpp.yml index a983a4c4ef..311df0bc88 100644 --- a/.github/workflows/build_cpp.yml +++ b/.github/workflows/build_cpp.yml @@ -221,6 +221,22 @@ jobs: run: build/Release/dtest.exe --runall -q - name: Build ancillary tools run: cmake --build build --config Release --target imglab htmlify dtoc --parallel 4 + - name: Install an AVX-enabled MSVC package + run: | + cmake ${{ github.workspace }} -B "${{ runner.temp }}/dlib-package-build" -DCMAKE_INSTALL_PREFIX="${{ runner.temp }}/dlib-package-install" -DDLIB_NO_GUI_SUPPORT=ON -DDLIB_USE_BLAS=OFF -DDLIB_USE_LAPACK=OFF -DDLIB_USE_CUDA=OFF -DUSE_AVX_INSTRUCTIONS=ON + cmake --build "${{ runner.temp }}/dlib-package-build" --config Release --target install --parallel 4 + - name: Test installed package with MSVC + run: | + cmake ${{ github.workspace }}/dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-msvc" -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake --build "${{ runner.temp }}/dlib-package-consumer-msvc" --config Release --parallel 4 + - name: Test installed MSVC package with clang++ + run: | + cmake ${{ github.workspace }}/dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang" -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake --build "${{ runner.temp }}/dlib-package-consumer-clang" --parallel 4 + - name: Test installed MSVC package with clang-cl + run: | + cmake ${{ github.workspace }}/dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang-cl" -G "Visual Studio 17 2022" -T ClangCL -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake --build "${{ runner.temp }}/dlib-package-consumer-clang-cl" --config Release --parallel 4 # Disable this because macos targets aren't working on github actions right now. #macos-latest: diff --git a/dlib/CMakeLists.txt b/dlib/CMakeLists.txt index 9c2304550b..cb63942cdf 100644 --- a/dlib/CMakeLists.txt +++ b/dlib/CMakeLists.txt @@ -806,17 +806,12 @@ if (NOT TARGET dlib) endif() target_compile_features(dlib PUBLIC cxx_std_14) - if((MSVC AND CMAKE_VERSION VERSION_LESS 3.11)) - # Old CMake/VS generators can't evaluate the generator expressions below. - target_compile_options(dlib PUBLIC ${active_compile_opts_gcc_public} ${active_compile_opts_msvc_public}) - target_compile_options(dlib PRIVATE ${active_compile_opts_private}) - else() - # Only forward each bucket of flags to consumers using a matching - # compiler (see https://github.com/davisking/dlib/issues/3125). - target_compile_options(dlib PUBLIC $<$:${active_compile_opts_gcc_public}>) - target_compile_options(dlib PUBLIC $<$:${active_compile_opts_msvc_public}>) - target_compile_options(dlib PRIVATE $<$:${active_compile_opts_private}>) - endif() + # Build-tree clients share dlib's compiler, so forward the options detected + # above to them. Do not put those options in the installed target, where + # dlibConfig.cmake recreates them for the consuming compiler's frontend. + target_compile_options(dlib INTERFACE "$:${active_compile_opts}>>") + target_compile_options(dlib PRIVATE $<$:${active_compile_opts}>) + target_compile_options(dlib PRIVATE $<$:${active_compile_opts_private}>) # Install the library if (NOT DLIB_IN_PROJECT_BUILD) diff --git a/dlib/cmake_utils/dlibConfig.cmake.in b/dlib/cmake_utils/dlibConfig.cmake.in index 4f7ea1ee28..4389b8182c 100644 --- a/dlib/cmake_utils/dlibConfig.cmake.in +++ b/dlib/cmake_utils/dlibConfig.cmake.in @@ -15,7 +15,7 @@ # Our library dependencies (contains definitions for IMPORTED targets) -if(NOT TARGET dlib-shared AND NOT dlib_BINARY_DIR) +if(NOT TARGET dlib::dlib AND NOT TARGET dlib-shared AND NOT dlib_BINARY_DIR) # Compute paths get_filename_component(dlib_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) include("${dlib_CMAKE_DIR}/dlib.cmake") @@ -29,6 +29,73 @@ if(NOT TARGET dlib-shared AND NOT dlib_BINARY_DIR) endif() unset(dlib_deps_threads_idx) unset(dlib_deps_threads_check) + + # Compiler options on an imported target are evaluated in the consuming + # project, not in the project that built dlib. Select them here so an + # installed package never passes (for example) cl-style options to the + # clang++ driver. MSVC is intentionally used instead of the compiler ID: + # CMake also sets it for compilers such as clang-cl that accept cl syntax. + set(_dlib_compile_options) + set(_dlib_compile_definitions) + set(_dlib_simd_level "@DLIB_SIMD_LEVEL@") + + if(MSVC) + list(APPEND _dlib_compile_options /bigobj) + + if(_dlib_simd_level STREQUAL "AVX") + list(APPEND _dlib_compile_options /arch:AVX) + elseif(_dlib_simd_level STREQUAL "SSE4") + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + list(APPEND _dlib_compile_options /arch:SSE2) + endif() + list(APPEND _dlib_compile_definitions DLIB_HAVE_SSE2 DLIB_HAVE_SSE3 DLIB_HAVE_SSE41) + elseif(_dlib_simd_level STREQUAL "SSE2") + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + list(APPEND _dlib_compile_options /arch:SSE2) + endif() + list(APPEND _dlib_compile_definitions DLIB_HAVE_SSE2) + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.3) + list(APPEND _dlib_compile_options -Xclang -fcxx-exceptions) + endif() + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) + list(APPEND _dlib_compile_options -ftemplate-depth=500) + endif() + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR + CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR + CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR + CMAKE_CXX_COMPILER_ID STREQUAL "Intel" OR + CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") + if(_dlib_simd_level STREQUAL "AVX") + list(APPEND _dlib_compile_options -mavx) + elseif(_dlib_simd_level STREQUAL "SSE4") + list(APPEND _dlib_compile_options -msse4) + elseif(_dlib_simd_level STREQUAL "SSE2") + list(APPEND _dlib_compile_options -msse2) + elseif(_dlib_simd_level STREQUAL "NEON") + list(APPEND _dlib_compile_options -mfpu=neon) + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + list(APPEND _dlib_compile_options -Wreturn-type) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) + list(APPEND _dlib_compile_options -ftemplate-depth=500) + endif() + endif() + + if(_dlib_compile_options) + target_compile_options(dlib::dlib INTERFACE "$<$:${_dlib_compile_options}>") + endif() + if(_dlib_compile_definitions) + target_compile_definitions(dlib::dlib INTERFACE "$<$:${_dlib_compile_definitions}>") + endif() + + unset(_dlib_compile_definitions) + unset(_dlib_compile_options) + unset(_dlib_simd_level) endif() set(dlib_LIBRARIES dlib::dlib) @@ -52,6 +119,3 @@ endfunction() variable_watch(dlib_LIBRARIES __deprecated_var) variable_watch(dlib_LIBS __deprecated_var) variable_watch(dlib_INCLUDE_DIRS __deprecated_var) - - - diff --git a/dlib/cmake_utils/set_compiler_specific_options.cmake b/dlib/cmake_utils/set_compiler_specific_options.cmake index e9dfa262e9..be05c88f45 100644 --- a/dlib/cmake_utils/set_compiler_specific_options.cmake +++ b/dlib/cmake_utils/set_compiler_specific_options.cmake @@ -24,27 +24,26 @@ endif() set(gcc_like_compilers GNU Clang Intel) set(intel_archs x86_64 i386 i686 AMD64 amd64 x86) +set(DLIB_SIMD_LEVEL NONE) # Setup some options to allow a user to enable SSE and AVX instruction use. -# -# NOTE: public flags go into active_compile_opts_gcc_public or -# active_compile_opts_msvc_public (instead of one shared list) so that -# dlib/CMakeLists.txt can forward each bucket only to consumers using a -# matching compiler. See https://github.com/davisking/dlib/issues/3125. if ((";${gcc_like_compilers};" MATCHES ";${CMAKE_CXX_COMPILER_ID};") AND (";${intel_archs};" MATCHES ";${CMAKE_SYSTEM_PROCESSOR};") AND NOT USE_AUTO_VECTOR) option(USE_SSE2_INSTRUCTIONS "Compile your program with SSE2 instructions" OFF) option(USE_SSE4_INSTRUCTIONS "Compile your program with SSE4 instructions" OFF) option(USE_AVX_INSTRUCTIONS "Compile your program with AVX instructions" OFF) if(USE_AVX_INSTRUCTIONS) - list(APPEND active_compile_opts_gcc_public -mavx) + set(DLIB_SIMD_LEVEL AVX) + list(APPEND active_compile_opts -mavx) message(STATUS "Enabling AVX instructions") elseif (USE_SSE4_INSTRUCTIONS) - list(APPEND active_compile_opts_gcc_public -msse4) + set(DLIB_SIMD_LEVEL SSE4) + list(APPEND active_compile_opts -msse4) message(STATUS "Enabling SSE4 instructions") elseif(USE_SSE2_INSTRUCTIONS) - list(APPEND active_compile_opts_gcc_public -msse2) + set(DLIB_SIMD_LEVEL SSE2) + list(APPEND active_compile_opts -msse2) message(STATUS "Enabling SSE2 instructions") endif() elseif (MSVC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # else if using Visual Studio @@ -56,23 +55,26 @@ elseif (MSVC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # else if using Visu include(CheckTypeSize) check_type_size( "void*" SIZE_OF_VOID_PTR) if(USE_AVX_INSTRUCTIONS) - list(APPEND active_compile_opts_msvc_public /arch:AVX) + set(DLIB_SIMD_LEVEL AVX) + list(APPEND active_compile_opts /arch:AVX) message(STATUS "Enabling AVX instructions") elseif (USE_SSE4_INSTRUCTIONS) + set(DLIB_SIMD_LEVEL SSE4) # Visual studio doesn't have an /arch:SSE2 flag when building in 64 bit modes. # So only give it when we are doing a 32 bit build. if (SIZE_OF_VOID_PTR EQUAL 4) - list(APPEND active_compile_opts_msvc_public /arch:SSE2) + list(APPEND active_compile_opts /arch:SSE2) endif() message(STATUS "Enabling SSE4 instructions") list(APPEND active_preprocessor_switches "-DDLIB_HAVE_SSE2") list(APPEND active_preprocessor_switches "-DDLIB_HAVE_SSE3") list(APPEND active_preprocessor_switches "-DDLIB_HAVE_SSE41") elseif(USE_SSE2_INSTRUCTIONS) + set(DLIB_SIMD_LEVEL SSE2) # Visual studio doesn't have an /arch:SSE2 flag when building in 64 bit modes. # So only give it when we are doing a 32 bit build. if (SIZE_OF_VOID_PTR EQUAL 4) - list(APPEND active_compile_opts_msvc_public /arch:SSE2) + list(APPEND active_compile_opts /arch:SSE2) endif() message(STATUS "Enabling SSE2 instructions") list(APPEND active_preprocessor_switches "-DDLIB_HAVE_SSE2") @@ -82,7 +84,8 @@ elseif((";${gcc_like_compilers};" MATCHES ";${CMAKE_CXX_COMPILER_ID};") AND ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "^arm")) option(USE_NEON_INSTRUCTIONS "Compile your program with ARM-NEON instructions" OFF) if(USE_NEON_INSTRUCTIONS) - list(APPEND active_compile_opts_gcc_public -mfpu=neon) + set(DLIB_SIMD_LEVEL NEON) + list(APPEND active_compile_opts -mfpu=neon) message(STATUS "Enabling ARM-NEON instructions") endif() endif() @@ -94,13 +97,13 @@ if (CMAKE_COMPILER_IS_GNUCXX) # By default, g++ won't warn or error if you forget to return a value in a # function which requires you to do so. This option makes it give a warning # for doing this. - list(APPEND active_compile_opts_gcc_public "-Wreturn-type") + list(APPEND active_compile_opts "-Wreturn-type") endif() if ("Clang" MATCHES ${CMAKE_CXX_COMPILER_ID} AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) # Clang 6 had a default template recursion depth of 256. This was changed to 1024 in Clang 7. # It must be increased on Clang 6 and below to ensure that the dnn examples don't error out. - list(APPEND active_compile_opts_gcc_public "-ftemplate-depth=500") + list(APPEND active_compile_opts "-ftemplate-depth=500") endif() if (MSVC) @@ -108,7 +111,7 @@ if (MSVC) # However, code generated by file_to_code_ex and code using DNN module can have # them. So this flag enables > 65k sections, but produces .obj files # that will not be readable by VS 2005. - list(APPEND active_compile_opts_msvc_public "/bigobj") + list(APPEND active_compile_opts "/bigobj") # Build dlib with all cores. Don't propagate the setting to client programs # though since they might compile large translation units that use too much @@ -117,9 +120,8 @@ if (MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.3) # Clang can compile all Dlib's code at Windows platform. Tested with Clang 5 - list(APPEND active_compile_opts_msvc_public -Xclang) - list(APPEND active_compile_opts_msvc_public -fcxx-exceptions) + list(APPEND active_compile_opts -Xclang) + list(APPEND active_compile_opts -fcxx-exceptions) endif() endif() - diff --git a/dlib/cmake_utils/test_for_avx/CMakeLists.txt b/dlib/cmake_utils/test_for_avx/CMakeLists.txt index 0367b1058f..44363bc5ec 100644 --- a/dlib/cmake_utils/test_for_avx/CMakeLists.txt +++ b/dlib/cmake_utils/test_for_avx/CMakeLists.txt @@ -4,13 +4,12 @@ project(avx_test) set(USE_AVX_INSTRUCTIONS ON CACHE BOOL "Use AVX instructions") -# Pull this in since it sets the AVX compile options by putting that kind of stuff into the -# active_compile_opts_gcc_public / active_compile_opts_msvc_public lists. +# Pull this in since it sets the AVX compile options by putting that kind of stuff into the active_compile_opts list. include(../set_compiler_specific_options.cmake) try_run(run_result compile_result ${PROJECT_BINARY_DIR}/avx_test_try_run_build ${CMAKE_CURRENT_LIST_DIR}/avx_test.cpp - COMPILE_DEFINITIONS ${active_compile_opts_gcc_public} ${active_compile_opts_msvc_public}) + COMPILE_DEFINITIONS ${active_compile_opts}) message(STATUS "run_result = ${run_result}") message(STATUS "compile_result = ${compile_result}") diff --git a/dlib/cmake_utils/test_for_dlib_config/CMakeLists.txt b/dlib/cmake_utils/test_for_dlib_config/CMakeLists.txt new file mode 100644 index 0000000000..e64217368a --- /dev/null +++ b/dlib/cmake_utils/test_for_dlib_config/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.17.0) + +project(dlib_config_test LANGUAGES CXX) + +find_package(dlib CONFIG REQUIRED) + +get_target_property(dlib_config_test_options dlib::dlib INTERFACE_COMPILE_OPTIONS) +find_package(dlib CONFIG REQUIRED) +get_target_property(dlib_config_test_options_after_second_find dlib::dlib INTERFACE_COMPILE_OPTIONS) +if(NOT "${dlib_config_test_options}" STREQUAL "${dlib_config_test_options_after_second_find}") + message(FATAL_ERROR "Finding the dlib package twice duplicated its compiler options") +endif() + +if(MSVC) + if(NOT ";${dlib_config_test_options};" MATCHES "/bigobj") + message(FATAL_ERROR "dlib::dlib did not provide /bigobj to an MSVC-style compiler frontend") + endif() +elseif(";${dlib_config_test_options};" MATCHES "/bigobj") + message(FATAL_ERROR "dlib::dlib provided /bigobj to a non-MSVC compiler frontend") +endif() + +if(DLIB_CONFIG_TEST_EXPECT_AVX) + if(MSVC) + if(NOT ";${dlib_config_test_options};" MATCHES "/arch:AVX") + message(FATAL_ERROR "dlib::dlib did not translate its AVX requirement to /arch:AVX") + endif() + elseif(NOT ";${dlib_config_test_options};" MATCHES "-mavx") + message(FATAL_ERROR "dlib::dlib did not translate its AVX requirement to -mavx") + endif() +endif() + +add_executable(dlib_config_test dlib_config_test.cpp) +target_link_libraries(dlib_config_test PRIVATE dlib::dlib) + +if(DLIB_CONFIG_TEST_EXPECT_AVX) + target_compile_definitions(dlib_config_test PRIVATE DLIB_CONFIG_TEST_EXPECT_AVX) +endif() diff --git a/dlib/cmake_utils/test_for_dlib_config/dlib_config_test.cpp b/dlib/cmake_utils/test_for_dlib_config/dlib_config_test.cpp new file mode 100644 index 0000000000..dc22ffc735 --- /dev/null +++ b/dlib/cmake_utils/test_for_dlib_config/dlib_config_test.cpp @@ -0,0 +1,10 @@ +#include + +#if defined(DLIB_CONFIG_TEST_EXPECT_AVX) && !defined(DLIB_HAVE_AVX) +#error "The installed dlib package did not enable AVX for its consumer" +#endif + +int main() +{ + return 0; +} diff --git a/dlib/cmake_utils/test_for_sse4/CMakeLists.txt b/dlib/cmake_utils/test_for_sse4/CMakeLists.txt index 0da5d7fd3d..6d3a5b372b 100644 --- a/dlib/cmake_utils/test_for_sse4/CMakeLists.txt +++ b/dlib/cmake_utils/test_for_sse4/CMakeLists.txt @@ -4,13 +4,12 @@ project(sse4_test) set(USE_SSE4_INSTRUCTIONS ON CACHE BOOL "Use SSE4 instructions") -# Pull this in since it sets the SSE4 compile options by putting that kind of stuff into the -# active_compile_opts_gcc_public / active_compile_opts_msvc_public lists. +# Pull this in since it sets the SSE4 compile options by putting that kind of stuff into the active_compile_opts list. include(../set_compiler_specific_options.cmake) try_run(run_result compile_result ${PROJECT_BINARY_DIR}/sse4_test_try_run_build ${CMAKE_CURRENT_LIST_DIR}/sse4_test.cpp - COMPILE_DEFINITIONS ${active_compile_opts_gcc_public} ${active_compile_opts_msvc_public}) + COMPILE_DEFINITIONS ${active_compile_opts}) message(STATUS "run_result = ${run_result}") message(STATUS "compile_result = ${compile_result}") From 23388986cee1ac0cce7b4725fbb0e8d00ee80278 Mon Sep 17 00:00:00 2001 From: Davis King Date: Sun, 9 Aug 2026 20:00:05 -0400 Subject: [PATCH 3/5] fix ci errors --- .github/workflows/build_cpp.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_cpp.yml b/.github/workflows/build_cpp.yml index 311df0bc88..edb84e6faa 100644 --- a/.github/workflows/build_cpp.yml +++ b/.github/workflows/build_cpp.yml @@ -223,19 +223,19 @@ jobs: run: cmake --build build --config Release --target imglab htmlify dtoc --parallel 4 - name: Install an AVX-enabled MSVC package run: | - cmake ${{ github.workspace }} -B "${{ runner.temp }}/dlib-package-build" -DCMAKE_INSTALL_PREFIX="${{ runner.temp }}/dlib-package-install" -DDLIB_NO_GUI_SUPPORT=ON -DDLIB_USE_BLAS=OFF -DDLIB_USE_LAPACK=OFF -DDLIB_USE_CUDA=OFF -DUSE_AVX_INSTRUCTIONS=ON + cmake . -B "${{ runner.temp }}/dlib-package-build" -DCMAKE_INSTALL_PREFIX="${{ runner.temp }}/dlib-package-install" -DDLIB_NO_GUI_SUPPORT=ON -DDLIB_USE_BLAS=OFF -DDLIB_USE_LAPACK=OFF -DDLIB_USE_CUDA=OFF -DUSE_AVX_INSTRUCTIONS=ON cmake --build "${{ runner.temp }}/dlib-package-build" --config Release --target install --parallel 4 - name: Test installed package with MSVC run: | - cmake ${{ github.workspace }}/dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-msvc" -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-msvc" -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-msvc" --config Release --parallel 4 - name: Test installed MSVC package with clang++ run: | - cmake ${{ github.workspace }}/dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang" -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang" -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-clang" --parallel 4 - name: Test installed MSVC package with clang-cl run: | - cmake ${{ github.workspace }}/dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang-cl" -G "Visual Studio 17 2022" -T ClangCL -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang-cl" -G "Visual Studio 17 2022" -T ClangCL -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-clang-cl" --config Release --parallel 4 # Disable this because macos targets aren't working on github actions right now. From d7db3b1b0b3dcfdd594dc4cf2c56b22deab58afc Mon Sep 17 00:00:00 2001 From: Davis King Date: Sun, 9 Aug 2026 21:18:35 -0400 Subject: [PATCH 4/5] try to fix CI again --- .github/workflows/build_cpp.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build_cpp.yml b/.github/workflows/build_cpp.yml index edb84e6faa..f56f4185d0 100644 --- a/.github/workflows/build_cpp.yml +++ b/.github/workflows/build_cpp.yml @@ -222,18 +222,22 @@ jobs: - name: Build ancillary tools run: cmake --build build --config Release --target imglab htmlify dtoc --parallel 4 - name: Install an AVX-enabled MSVC package + working-directory: ${{ github.workspace }} run: | cmake . -B "${{ runner.temp }}/dlib-package-build" -DCMAKE_INSTALL_PREFIX="${{ runner.temp }}/dlib-package-install" -DDLIB_NO_GUI_SUPPORT=ON -DDLIB_USE_BLAS=OFF -DDLIB_USE_LAPACK=OFF -DDLIB_USE_CUDA=OFF -DUSE_AVX_INSTRUCTIONS=ON cmake --build "${{ runner.temp }}/dlib-package-build" --config Release --target install --parallel 4 - name: Test installed package with MSVC + working-directory: ${{ github.workspace }} run: | cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-msvc" -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-msvc" --config Release --parallel 4 - name: Test installed MSVC package with clang++ + working-directory: ${{ github.workspace }} run: | cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang" -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-clang" --parallel 4 - name: Test installed MSVC package with clang-cl + working-directory: ${{ github.workspace }} run: | cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang-cl" -G "Visual Studio 17 2022" -T ClangCL -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-clang-cl" --config Release --parallel 4 From d5e0db7039571f50a397c0b4cfd29081df040d2d Mon Sep 17 00:00:00 2001 From: Davis King Date: Sun, 9 Aug 2026 21:52:07 -0400 Subject: [PATCH 5/5] maybe now --- .github/workflows/build_cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_cpp.yml b/.github/workflows/build_cpp.yml index f56f4185d0..226d24d4bf 100644 --- a/.github/workflows/build_cpp.yml +++ b/.github/workflows/build_cpp.yml @@ -239,7 +239,7 @@ jobs: - name: Test installed MSVC package with clang-cl working-directory: ${{ github.workspace }} run: | - cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang-cl" -G "Visual Studio 17 2022" -T ClangCL -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON + cmake dlib/cmake_utils/test_for_dlib_config -B "${{ runner.temp }}/dlib-package-consumer-clang-cl" -T ClangCL -Ddlib_DIR="${{ runner.temp }}/dlib-package-install/lib/cmake/dlib" -DDLIB_CONFIG_TEST_EXPECT_AVX=ON cmake --build "${{ runner.temp }}/dlib-package-consumer-clang-cl" --config Release --parallel 4 # Disable this because macos targets aren't working on github actions right now.