尝试使用CMake和MinGW64进行构建时出现多个重定义错误

史蒂文

我遇到了一个似乎无法解决的问题。我正在尝试构建一个使用名为spdlog的日志记录库的项目,但是当我在项目中使用它时将无法构建该项目。MinGW64报告说某些功能有多种定义:

Scanning dependencies of target Application
[ 91%] Building CXX object Application/CMakeFiles/Application.dir/src/main.cpp.obj
[100%] Linking CXX executable ..\Debug\bin\Application.exe
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `std::is_same<long double, float> fmt::v6::internal::const_check<std::is_same<long double, float> >(std::is_same<long double, float>)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:58: multiple definition of `fmt::v6::internal::assert_fail(char const*, int, char const*)'
../Debug/lib/libTools.dll.a(d000329.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `fmt::v6::format_error::~format_error()':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format.h:691: multiple definition of `fmt::v6::format_error::~format_error()'
../Debug/lib/libTools.dll.a(d000167.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `fmt::v6::internal::error_handler::on_error(char const*)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:1363: multiple definition of `fmt::v6::internal::error_handler::on_error(char const*)'
../Debug/lib/libTools.dll.a(d000735.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `std::string fmt::v6::internal::grouping_impl<char>(fmt::v6::internal::locale_ref)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:203: multiple definition of `std::string fmt::v6::internal::grouping_impl<char>(fmt::v6::internal::locale_ref)'
../Debug/lib/libTools.dll.a(d000741.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `char fmt::v6::internal::thousands_sep_impl<char>(fmt::v6::internal::locale_ref)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:206: multiple definition of `char fmt::v6::internal::thousands_sep_impl<char>(fmt::v6::internal::locale_ref)'
../Debug/lib/libTools.dll.a(d000999.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `char fmt::v6::internal::decimal_point_impl<char>(fmt::v6::internal::locale_ref)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:210: multiple definition of `char fmt::v6::internal::decimal_point_impl<char>(fmt::v6::internal::locale_ref)'
../Debug/lib/libTools.dll.a(d000994.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `int fmt::v6::internal::snprintf_float<double>(double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:1117: multiple definition of `int fmt::v6::internal::snprintf_float<double>(double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)'
../Debug/lib/libTools.dll.a(d000876.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `int fmt::v6::internal::snprintf_float<long double>(long double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:1117: multiple definition of `int fmt::v6::internal::snprintf_float<long double>(long double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)'
../Debug/lib/libTools.dll.a(d000877.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `int fmt::v6::internal::format_float<double>(double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:1045: multiple definition of `int fmt::v6::internal::format_float<double>(double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)'
../Debug/lib/libTools.dll.a(d000693.o):(.text+0x0): first defined here
../Debug/lib/libspdlogd.a(fmt.cpp.obj): In function `int fmt::v6::internal::format_float<long double>(long double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)':
D:/Development/git/cmaketest/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h:1045: multiple definition of `int fmt::v6::internal::format_float<long double>(long double, int, fmt::v6::internal::float_specs, fmt::v6::internal::buffer<char>&)'
../Debug/lib/libTools.dll.a(d000695.o):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [Application\CMakeFiles\Application.dir\build.make:88: Debug/bin/Application.exe] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:190: Application/CMakeFiles/Application.dir/all] Error 2
mingw32-make: *** [Makefile:83: all] Error 2 

现在,我已经完成了一个单独的项目,该项目具有重现此问题所需的最低限度的费用,希望找到解决方案,但我得到的结果是相同的。我也尝试过通过Visual Studio进行构建,并且可以正常工作,尽管创建lib的方式当然有所不同。还尝试了不同版本的MinGW64,但不幸的是,它也无法解决。

为了演示该问题,这里是“裸机”项目的内容。

我的项目分为三个部分:应用程序,third_party和工具。在这种情况下,Third_party包含spdlog存储库的git子模块

应用程序包含一个文件main.cpp,具有以下内容

#include "Logger.h"
#include <iostream>

int main()
{
    DEBUGERROR("error in main {}", 1);
    getchar();
    return 0;
}

工具包括以下内容:

记录器

#pragma once
#include <string>
#include <iostream>
#include <spdlog/spdlog.h>

#define DEBUGERROR(userFormat,...) spdlog::error("[{}] [{}:{}] " userFormat, __COMPONENT__, __func__, __LINE__, ##__VA_ARGS__);
#define DEBUGINFO(userFormat,...) spdlog::info("[{}] [{}:{}] " userFormat, __COMPONENT__, __func__, __LINE__, ##__VA_ARGS__);;
#define DEBUGWARNING(userFormat,...) spdlog::warn("[{}] [{}:{}] " userFormat, __COMPONENT__, __func__, __LINE__, ##__VA_ARGS__);
#define DEBUGCRITICAL(userFormat,...) spdlog::critical("[{}] [{}:{}] " userFormat, __COMPONENT__, __func__, __LINE__, ##__VA_ARGS__);

namespace Tools
{
    class Logger
    {
    public:
        void Logger::init()
        {
            spdlog::set_pattern("%^[thread %t] [%H:%M:%S] [%l] [%s:%#] %v%$");
        }
    };
} 

打印机

#pragma once

class Printer
{
public:
    Printer();
    virtual ~Printer();
    static void printError();
private:
}; 

打印机.cpp

#include "printer.h"
#include "Logger.h"

Printer::Printer()
{

}
Printer::~Printer()
{

}

void Printer::printError()
{
    DEBUGERROR("printing an error {}", 1);
} 

为此,我创建了3个cmake文件。

根CMakeLists.txt

cmake_minimum_required(VERSION 3.15.3)
project(AllProjects LANGUAGES CXX C)

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

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/bin)

add_subdirectory("third_party/spdlog")
add_subdirectory("Tools")
add_subdirectory("Application") 

应用程序CMakeLists.txt

cmake_minimum_required(VERSION 3.15.3)
project(Application LANGUAGES CXX C)
add_definitions( /D__COMPONENT__="app" )

file(GLOB_RECURSE SOURCES src/*.cpp)

set(INCLUDEDIR ${PROJECT_SOURCE_DIR}/include
               ${CMAKE_SOURCE_DIR}/Tools/include
)

include_directories(${INCLUDEDIR})
add_executable(Application ${SOURCES})
target_link_libraries (Application Tools) 

工具CMakeLists.txt

cmake_minimum_required(VERSION 3.15.3)
project(Tools LANGUAGES CXX C)

add_definitions( /D__COMPONENT__="tools" )

file(GLOB_RECURSE SOURCES src/*.cpp
)

set(INCLUDEDIR ${PROJECT_SOURCE_DIR}/include
    ${CMAKE_SOURCE_DIR}/third_party/spdlog/include
)

include_directories(${INCLUDEDIR})

add_library(Tools SHARED ${SOURCES})
target_link_libraries (Tools spdlog) 

最后,我使用以下命令集来构建所有内容:

cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DBUILD_SHARED_LIBS=TRUE -G "MinGW Makefiles" ..
mingw32-make
cd .. 

因此,最终,该项目的结构如下:

项目

  • 应用
    • 包括
    • src
    • CMakeLists.txt
  • 工具类
    • 包括
    • src
    • CMakeLists.txt
  • 第三方
    • spdlog存储库作为git子模块
  • CMakeLists.txt

仅当我开始在多个文件中包含Logger.h时,问题才开始出现。我希望我已提供足够的信息来使问题明确。任何帮助将不胜感激!

史蒂文

我找到了一个可行的解决方案,但有一个副作用,必须在包含工具的项目中单独包含spdlog。在Tools CMakeLists.txt中,我必须将“ target_link_libraries(Tools spdlog)”的最后一行更改为target_link_libraries(Tools PRIVATE spdlog)。之后,我确实必须在应用程序的包含路径中添加“ $ {CMAKE_SOURCE_DIR} / third_party / spdlog / include”。出于某种原因,spdlog是唯一需要我以这种方式执行的外部项目。并不是我真正想要的,因为我现在必须在所有需要它的未来项目中将spdlog和工具一起包括在内,但是它确实可以正常工作。

更新了工具CMakeLists.txt

cmake_minimum_required(VERSION 3.15.3)
project(Tools LANGUAGES CXX C)

add_definitions( /D__COMPONENT__="tools" )

file(GLOB_RECURSE SOURCES src/*.cpp
)

set(INCLUDEDIR ${PROJECT_SOURCE_DIR}/include
    ${CMAKE_SOURCE_DIR}/third_party/spdlog/include
)

include_directories(${INCLUDEDIR})

add_library(Tools SHARED ${SOURCES})
target_link_libraries (Tools PRIVATE spdlog) 

更新了应用程序CMakeLists.txt

cmake_minimum_required(VERSION 3.15.3)
project(Application LANGUAGES CXX C)
add_definitions( /D__COMPONENT__="app" )

file(GLOB_RECURSE SOURCES src/*.cpp)

set(INCLUDEDIR ${PROJECT_SOURCE_DIR}/include
               ${CMAKE_SOURCE_DIR}/Tools/include
               ${CMAKE_SOURCE_DIR}/third_party/spdlog/include
)

include_directories(${INCLUDEDIR})
add_executable(Application ${SOURCES})
target_link_libraries (Application Tools) 

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

cmake mingw-w64:尝试构建时出现奇怪的错误

使用 MinGW 4.9.2 构建 glew 2.0.0 时出现 Cmake 错误

尝试使用标头(QPID / Proton C ++)进行构建时出现“未定义的引用”链接错误

尝试使用cmake构建游戏“ M博士的秘密编年史”时出现错误

使用 MinGW64 时不会抛出错误 C2057

尝试使用 cURL 时出现多个错误

使用CMake和NMake构建OpenCV 3.0时出现链接错误

尝试使用 PyTube 和 Tkinter 构建时出现正则表达式错误

尝试使用角度 UI 执行获取请求时出现 base 64 图像未定义错误

尝试使用按钮运行多个宏时出现“未定义子或函数”错误

尝试构建或使用新主题时出现与Git相关的错误

使用多个文件时出现“架构 x86_64 的未定义符号”错误

尝试使用 reddit api 和 python 3 进行身份验证时出现 401 错误

使用msys / mingw64构建marisa-trie共享库

MinGW / MinGW64链接和对msvcrt.dll的依赖

使用mingw和cmake构建opencv时出错:“ windres.exe:无效选项-W”

尝试在 Visual Studio 工作时使用来自 CLION 的 Boost 1.69.0,但出现奇怪的 MINGW 错误

使用汇编嵌入数据时出现“未定义引用”错误,使用 mingw-w64 编译 windows(COFF 而不是 ELF)

在Linux和mingw64上使用CRLF行尾的不同awk结果

尝试删除多个目录时出现错误

使用Angular和Kendo UI进行AOT构建时出现错误“标识符'territoryFromName'已经声明”

链接C但仅在MinGW上出现“多个定义”错误

在 python 中加载自定义 dll 时出现依赖错误,使用 Visual Studio 2017 和 boost 构建

尝试使用自定义工具栏和导航组件设置后退按钮时出现空错误

尝试在 Maven 发布准备和执行任务上运行并行构建时出现 Ger 错误?

尝试使用云构建 (gcp) 进行部署时出现未找到的 URL

编译时出现Cmake和Qt错误

尝试通过管道传递别名定义中的多个命令时出现语法错误

构建Wireshark时出现错误和警告