1

I am learning to build library with the following command

cmake -S . -B .\build\ -DCMAKE_BUILD_TYPE=Debug
cmake --build .\build\

I am getting the following errors during cmake --build .\build\

error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.obj
error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.obj 

I was referring the question at the error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.obj to solve the error error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.obj but would like to know how to implement their solution using cmake.
I referred the answer to solve the problem but it didn't solve the error.

Second problem is that I can't understand why MD_DynamicRelease is being built even though I added the option -DCMAKE_BUILD_TYPE=Debug.


Root CMakeLists.txt File

cmake_minimum_required(VERSION 3.16)

project(CppProjectTemplate VERSION 1.0.0 LANGUAGES C CXX)


set(CMAKE_CXX_STANDARD              17)
set(CMAKE_CXX_STANDARD_REQUIRED     ON)
set(CMAKE_CXX_EXTENSIONS            OFF)

set(MY_LIBRARY_NAME Library)


#Chapter 22 Starts Here --> Needs to be a cmake project else can't be used
include(FetchContent)
FetchContent_Declare(
    nlohmann_json # Must be the same name as mentioned in the main (root) cmake project file
    GIT_REPOSITORY https://github.com/nlohmann/json
    GIT_TAG v3.11.2
    GIT_SHALLOW TRUE #Won't clone recurrsively
)
FetchContent_MakeAvailable(nlohmann_json)# Must be the same name as mentioned in the main (root) cmake project file

FetchContent_Declare(
    fmt # Must be the same name as mentioned in the main (root) cmake project file
    GIT_REPOSITORY https://github.com/fmtlib/fmt
    GIT_TAG 9.1.0
    GIT_SHALLOW TRUE #Won't clone recurrsively
)
FetchContent_MakeAvailable(fmt)# Must be the same name as mentioned in the main (root) cmake project file

FetchContent_Declare(
    spdlog # Must be the same name as mentioned in the main (root) cmake project file
    GIT_REPOSITORY https://github.com/gabime/spdlog
    GIT_TAG v1.11.0
    GIT_SHALLOW TRUE #Won't clone recurrsively
)
FetchContent_MakeAvailable(spdlog)# Must be the same name as mentioned in the main (root) cmake project file

FetchContent_Declare(
    cxxopts # Must be the same name as mentioned in the main (root) cmake project file
    GIT_REPOSITORY https://github.com/jarro2783/cxxopts
    GIT_TAG v3.0.0
    GIT_SHALLOW TRUE #Won't clone recurrsively
)
FetchContent_MakeAvailable(cxxopts)# Must be the same name as mentioned in the main (root) cmake project file

FetchContent_Declare(
    Catch2 # Must be the same name as mentioned in the main (root) cmake project file
    GIT_REPOSITORY https://github.com/catchorg/Catch2
    GIT_TAG v2.13.9
    GIT_SHALLOW TRUE #Won't clone recurrsively
)
FetchContent_MakeAvailable(Catch2)# Must be the same name as mentioned in the main (root) cmake project file
# Chapter 22 Ends Here
# Enable/Disable option using -D<Option-Name>=1 or 0 e.g. -DCOMPILE_EXECUTABLE=1
option(COMPILE_EXECUTABLE "Whether to compile the executable" ON) 

add_subdirectory(src)
add_subdirectory(test)

src folder

my_lib.hh

#pragma once
#include <cstdint>
void print_hello_world(void);
std::uint32_t factorial(std::uint32_t number);

my_lib.cc

#include <iostream>
#include "my_lib.hh"
#include <nlohmann/json.hpp>
#include <fmt/format.h>
#include <spdlog/spdlog.h>
#include <cxxopts.hpp>

/**
 * @brief Print out Hello, World!!! and print the version of nlohmann-json, fmt-format, cxxopts and spdlog library
 * 
 */
void print_hello_world(void)
{
    std::cout << "Hello, World!!!" << std::endl;
    std::cout << "Json Lib Version (Inside print_hello_world) : "   
        << NLOHMANN_JSON_VERSION_MAJOR << "."
        << NLOHMANN_JSON_VERSION_MINOR << "."
        << NLOHMANN_JSON_VERSION_PATCH << std::endl;

    std::cout << "FMT Version (Inside print_hello_world) : "    
        << FMT_VERSION << std::endl;

    std::cout << "cxxopts Version (Inside print_hello_world) : "    
        << CXXOPTS__VERSION_MAJOR << "."
        << CXXOPTS__VERSION_MINOR << "."
        << CXXOPTS__VERSION_PATCH << std::endl;

    std::cout << "spdlogs Version (Inside print_hello_world) : "    
        << SPDLOG_VER_MAJOR << "."
        << SPDLOG_VER_MINOR << "."
        << SPDLOG_VER_PATCH << std::endl;
}

std::uint32_t factorial(std::uint32_t number)
{
    return number <= 1 ? number : factorial(number-1) * number;
}

src CMakeLists.txt

set(
    LIBRARY_SOURCES 
    "my_lib.cc"
    )

set(LIBRARY_HEADERS 
    "my_lib.hh")

add_library(${MY_LIBRARY_NAME} STATIC ${LIBRARY_SOURCES} ${LIBRARY_HEADERS})

target_include_directories(${MY_LIBRARY_NAME} PUBLIC 
    "./"
    "${CMAKE_BINARY_DIR}/configured_files/include"
)

target_link_libraries(${MY_LIBRARY_NAME} PUBLIC 
    nlohmann_json::nlohmann_json
    cxxopts::cxxopts
    fmt::fmt
    spdlog::spdlog
)

Test Directory

CMakeLists.txt

set(TEST_PROJECT "TestExecutable")
set(TEST_SOURCES "main.cc")
set(TEST_INCLUDE "./")

add_executable(${TEST_PROJECT} ${TEST_SOURCES})
target_include_directories(${TEST_PROJECT} PUBLIC ${TEST_INCLUDE})
target_link_libraries(${TEST_PROJECT} PUBLIC ${MY_LIBRARY_NAME} Catch2::Catch2)

main.cc

#define CATCH_CONFIG_MAIN

#include "catch.hpp"
#include "my_lib.hh"

TEST_CASE("Factorial are computed", "[Factorial]")
{
    REQUIRE(factorial(1) == 1);
    REQUIRE(factorial(2) == 2);
    REQUIRE(factorial(3) == 6);
    REQUIRE(factorial(10) == 3628800);
}
6
  • When build the project with Visual Studio generator, build type isn't known at configuration stage, when cmake -S <..> -B <..> is run and when CMakeLists.txt is processed. Setting CMAKE_BUILD_TYPE with such generator is at least useless and could confuse other projects which you use as subprojects. With Visual Studio build type is specified with --config option to cmake --build invocation. Commented Jan 26, 2023 at 7:52
  • @Tsyvarev, I tried the following command but still getting the same error cmake -S . -B build\ -DCMAKE_BUILD_TYPE=Debug and cmake --build .\build\ --config Debug Commented Jan 26, 2023 at 14:12
  • Do not use -DCMAKE_BUILD_TYPE option at all. And make clean configuration (with empty build directory). Commented Jan 26, 2023 at 14:32
  • @Tsyvarev Tried all permutation and combinations. I'm still getting the same error. Commented Jan 26, 2023 at 15:09
  • @DarkSorrow is this happening in the test project? Commented Jan 30, 2023 at 9:07

1 Answer 1

1

Based on your reply to my comment the issue is in this line:

target_link_libraries(${TEST_PROJECT} PUBLIC ${MY_LIBRARY_NAME} Catch2::Catch2)

I've faced similar issues and it's caused by not linking the debug library of Catch2 in DEBUG builds (but instead the release libraries). To fix this you need to use generator expressions for linking Catch2. I do not have a concrete example (it's been years since I've used Catch2), but you ideally need to link the actual Catch2 library without using the alias Catch2::Catch2 and use generator expressions to specify the debug library. e.g. you need something like:

target_link_libraries(${TEST_PROJECT} PUBLIC ${MY_LIBRARY_NAME} Catch2<$<$CMAKE_BUILD_TYPE:DEBUG>d>)

Where Catch2 is the actual library target and not the alias i.e. Catch2::Catch2. The generator expression basically expands to Catch2d when CMAKE_BUILD_TYPE == DEBUG.


EDIT: As DarkSorrow mentions in the comments below, this has resolved the issue for him

target_link_libraries(${TEST_PROJECT} PUBLIC ${MY_LIBRARY_NAME} Catch2$<$<CONFIG:Debug>:d>)
Sign up to request clarification or add additional context in comments.

2 Comments

I used the following command target_link_libraries(${TEST_PROJECT} PUBLIC ${MY_LIBRARY_NAME} Catch2$<$<CONFIG:Debug>:d>) to build the library,
@DarkSorrow Will put an edit to the answer to include it for other people. Glad it's fixed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.