链接错误使用 CMake 在C++中创建共享库,因为符号的多重定义

Linking error using CMake to create a shared library in C++ because multiple definition of symbol

本文关键字:因为 符号 定义 共享 创建 错误 CMake C++ 链接      更新时间:2023-10-16

我在编译与 POCO C++库链接的代码以创建 Linux 共享库(Mint 13,以防万一(时遇到问题。这是我减少的环境。

我有这 3 个文件:

IL_Notify.h

#ifndef __IL_NOTIFY_H__
#define __IL_NOTIFY_H__
#include <string>
#include "Poco/Logger.h"
#include "Poco/LogStream.h"
using Poco::Logger;
using Poco::LogStream;
namespace mynamespace
{
    // Get logger. Inherits root channel
    LogStream lstr(Logger::get("MyLogger"));
    // From any other class, call logger this way:
    //lstr << "This is a test" << std::endl;
}
#endif

IL_Class1.cpp

#include "IL_Class1.h"
#include "IL_Notify.h"
namespace mynamespace {
    void IL_Class1::foo()
    {
        // Stuff...
        lstr << "This is a test msg from IL_Class1::foo" << std::endl;
    }
}

IL_Class2.cpp

#include "IL_Class2.h"
#include "IL_Notify.h"
namespace mynamespace {
    void IL_Class2::bar()
    {
        // Stuff...
        lstr << "This is a test msg from IL_Class2::bar" << std::endl;
    }
}

IL_Class1IL_Class2IL_Class1.hIL_Class2.h声明。这些标头中不包含IL_Notify.h

这是我的CMakeLists.txt文件

# Set search path to find PocoConfig.cmake
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules/)

# Look for needed packages
find_package(Poco REQUIRED)
# Now, we can use poco
include_directories(
    ${Poco_INCLUDE_DIRS}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)
# Libraries which we are linking against
link_directories(
    ${Poco_LIBRARY_DIRS}
)
# Get all the cpp files to build my library
file(GLOB_RECURSE all_sources
    ${CMAKE_CURRENT_SOURCE_DIR}/src/IL_Class1.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/src/IL_Class2.cpp
)
# Library creation
add_library(mylib SHARED ${all_sources})

我可以成功执行cmake,以创建Makefile.但是当我运行make时,我收到此错误

CMakeFiles/mylib.dir/src/IL_Class2.cpp.o:(.bss+0x0): multiple definition of `mynamespace::lstr'
CMakeFiles/mylib.dir/src/IL_Class1.cpp.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [libmylib.so] Error 1
make[1]: *** [CMakeFiles/mylib.dir/all] Error 2
make: *** [all] Error 2

因此,即使我通过 #ifndef 阻止包含两次标头,make也无法编译我的代码,因为该标头中声明的符号被检测到两次。为什么?

看到我的问题重复后,我得到了正确的解决方案。

我的IL_Notify.h

#ifndef __IL_NOTIFY_H__
#define __IL_NOTIFY_H__
#include <string>
#include "Poco/Logger.h"
#include "Poco/LogStream.h"
using Poco::Logger;
using Poco::LogStream;
namespace openil
{
    // Get logger. Inherits root channel
    extern LogStream lstr;
}
#endif

我的IL_Notify.cpp

#include "IL_Notify.h"
namespace openil
{
    // TODO: More flexibility here: more channels, different formatting...
    // Maybe a IL_Utils function should do that
    // Get logger. Inherits root channel
    LogStream lstr(Logger::get("OpenILLogger"));
    // From any other class, call logger this way:
    //lstr << "This is a test" << std::endl;
}