CMake with MSVC and spdlog warnings

  c++, cmake, visual-c++

I’m using CMake to build a project that includes the spdlog library. At present, I’m doing so with Visual Studio, but I’m more used to Linux/GCC for what it’s worth. Anyway, I’m having a heck of a time getting MSVC to treat spdlog as the external dependency that it is. Here’s what I’ve got:

CMakeLists.txt from the root:

cmake_minimum_required(VERSION 3.16)

project(spdlogtest)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")

find_package(spdlog REQUIRED)

add_executable(
    spdlogtest
    main.cpp
)

target_include_directories(
    spdlogtest SYSTEM PUBLIC
    ${spdlog_SOURCE_DIR}/include/
)

target_compile_options(
    spdlogtest PUBLIC
    /Od /EHsc /nologo /MP /sdl /Wall
    /external:W0
)

target_compile_definitions(
    spdlogtest PUBLIC
    DEBUG
)

set_target_properties(
    spdlogtest PROPERTIES
    CXX_STANDARD 20
    CXX_STANDARD_REQUIRED ON
    BINARY_OUTPUT_DIRECTORY_DEBUG   ${CMAKE_SOURCE_DIR}/debug/bin
    BINARY_OUTPUT_DIRECTORY_DEBUG   ${CMAKE_SOURCE_DIR}/release/bin
)

Findspdlog.cmake:

message(STATUS "Pulling in external spdlog")

include(FetchContent)

FetchContent_Declare(
    spdlog
    GIT_REPOSITORY https://github.com/gabime/spdlog.git
    GIT_TAG eb3220622e73a4889eee355ffa37972b3cac3df5 # v1.9.2
)
FetchContent_MakeAvailable(spdlog)

And finally main.cpp is just the quickstart example from the GitHub page.

#include "spdlog/spdlog.h"

int main()
{
    spdlog::info("Welcome to spdlog!");
    spdlog::error("Some error message with arg: {}", 1);
    
    spdlog::warn("Easy padding in numbers like {:08d}", 12);
    spdlog::critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
    spdlog::info("Support for floats {:03.2f}", 1.23456);
    spdlog::info("Positional args are {1} {0}..", "too", "supported");
    spdlog::info("{:<30}", "left aligned");
    
    spdlog::set_level(spdlog::level::debug); // Set global log level to debug
    spdlog::debug("This message should be displayed..");    
    
    // change log pattern
    spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
    
    // Compile time log levels
    // define SPDLOG_ACTIVE_LEVEL to desired level
    SPDLOG_TRACE("Some trace message with param {}", 42);
    SPDLOG_DEBUG("Some debug message");
}

Basically, if I’ve got the compiler set to /W4, everything compiles without a hitch. If I set it to /Wall though, I get 100+ warnings that mostly seem to come from the libfmt included in spdlog. I’ve tried using an external libfmt, but achieve much the same result.

I prefer /Wall (and -pedantic) while I’m writing my own code. Holding other people to that standard is ridiculous though, so mark the fetched project as a system include and you’re good, right? I certainly thought so.

The CMakeLists.txt from the root produces the massive warnings, as do the variations I’ve attempted. On the plus side, I think I’m better at CMake than I was when I started.

This suggestion worked for me some time in the past, but doesn’t seem to affect behavior here. Adding the flag /external:I${spdlog_SOURCE_DIR}/include directly to target_compile_options() also doesn’t affect anything. I also tried brute forcing it and using GLOB_RECURSE to mark all of the files in ${spdlog_SOURCE_DIR} as explicitly /W0 after fetching them, but no luck there either.

If anyone can point me in the right direction and explain why what I’m trying to do is failing, I’d be very grateful.

Source: Windows Questions C++

LEAVE A COMMENT