首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用cmake链接c++项目构建的多个定义

用cmake链接c++项目构建的多个定义
EN

Stack Overflow用户
提问于 2021-10-16 12:05:48
回答 1查看 914关注 0票数 0

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

below).

  • Declared
  • 正确地包含了我的标题(在标头中没有定义,而是没有定义产生错误的变量。CMakeLists.txt中的
  • 包含了标题,并正确地添加到可执行文件中。

)

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

代码语言:javascript
复制
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
  • /include/gui/
    • /gui /gui

test.h patata.h

  • /src/

patata.cpp main.cpp test.cpp

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

代码语言:javascript
复制
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}")

我已经多次检查了我的头部,以确定我没有在它们上定义任何东西,我甚至还设置了守卫:

test.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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看起来是这样的:

代码语言:javascript
复制
#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();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-16 12:29:26

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69595429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档