【问题标题】:Multiple definition linking c++ project build with cmake [duplicate]将c ++项目构建与cmake链接的多个定义[重复]
【发布时间】:2021-12-04 06:58:16
【问题描述】:

首先,如果这以一个菜鸟问题结束,我很抱歉,但我掌握了 CMake,但我在这里找不到问题。它是一个多重定义错误,但只要我知道我有:

  • 正确包含我的标题(发布在下面)。
  • 在标题中声明但未定义给出错误的变量。
  • 在 CMakeLists.txt 中包含标题并将文件正确添加到可执行文件中。

显然其中一些是谎言,因为在链接可执行文件时出现下一个错误:

CMakeFiles/helloworld.dir/src/test.cpp.o:(.bss+0x0): multiple definition of `b'
CMakeFiles/helloworld.dir/src/main.cpp.o:(.bss+0x0): first defined here   
CMakeFiles/helloworld.dir/src/test.cpp.o:(.bss+0x4): multiple definition of `_patata' 
CMakeFiles/helloworld.dir/src/main.cpp.o:(.bss+0x4): first defined here 

我的 C++ 项目结构是这样的;

  • /gui
    • CMakeLists.txt
    • /include/gui/
      test.h patata.h
    • /src/
      main.cpp test.cpp patata.cpp

在我的 CMakeLists.txt 中,我包含带有标题的文件夹,并添加了一个名为 helloworld 的可执行文件,该可执行文件将从 src 文件夹中的文件构建。

cmake_minimum_required (VERSION 3.1.0)
project(gui)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

if(CMAKE_VERSION VERSION_LESS "3.7.0")
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()

set(CMAKE_PREFIX_PATH   ${CMAKE_PREFIX_PATH} $ENV{QTDIR})

# Dependencies
find_package(Qt5 COMPONENTS Widgets REQUIRED)

# Files
file(GLOB_RECURSE SRCS  "${PROJECT_SOURCE_DIR}/src/*.c*")

# Include
include_directories("${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/src")

# Target
add_executable(helloworld
    ${SRCS}
)

# Libs
target_link_libraries(helloworld Qt5::Widgets)

# Logs
message(STATUS "SOURCES DIR => ${PROJECT_SOURCE_DIR}/src/")
message(STATUS "SOURCES FILES => ${SRCS}")

我已经检查了多次我的标题,以确保我没有在它们上定义任何东西,我什至设置了警卫:

测试.h

#pragma once
#ifndef TEST_H
#define TEST_H

#include <string>
#include <gui/patata.h>

//std::string meh;
int b;
patata _patata;
std::string message();
#endif

test.cpp

#include <gui/test.h>
#include <gui/patata.h>

std::string message(){    
    //meh = "print";
    b=1;
    std::cout << b << std::endl;
    std::cout << _patata.rn() << std::endl;
    std::string meh = "snn";
    return meh;
}

我知道问题出在链接中,但我不知道为什么链接器会看到变量的两个定义。 test.cpp 是否编译了两次?如果是这样,我该如何防止这种情况?我认为所有的 .cpp 文件都应该添加到可执行文件中,编译器将无法找到声明,但也许我错了。

我的 main.cpp 看起来像这样:

#include <QCoreApplication>
#include <QDebug>
#include <gui/test.h>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    std::cout << message() << std::endl;
    qDebug() << "Hello World";
    
    return a.exec();
}

【问题讨论】:

    标签: c++ cmake linker


    【解决方案1】:

    您在 test.h 中声明了 b_patata。由于 test.cpp 和 main.cpp 都包含 test.h,那么 test.cpp 和 main.cpp 翻译单元都有一个名为 b_patata 的全局变量。现在各有两个。每个只能有一个。解决方案是将int b;patata _patata; 移动到test.cpp 中,因为它们不需要在test.h 中。 阅读 C++ 链接规则。

    【讨论】:

    • 我看到这确实是一个菜鸟问题,哈哈,我没想过。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多