多定义链接 C++ 项目构建与 cmake

Multiple definition linking c++ project build with cmake

首先,如果这以一个菜鸟问题结尾,我很抱歉,但我正在掌握 CMake,我找不到这里的问题。这是一个多重定义错误,但据我所知我有:

显然其中有些是谎言,因为我在链接我的可执行文件时遇到了下一个错误:

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++ 项目结构如下;

在我的 CMakeLists.txt 中,我将文件夹包含在 headers 中,并添加一个名为 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}")

我检查了我的 headers 多次,以确保我没有在它们上面定义任何东西,我什至还设置了防护装置:

test.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();
}

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