[英]Linking error using CMake to create a shared library in C++ because multiple definition of symbol
我在編譯與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_Class1
和IL_Class2
在IL_Class1.h
和IL_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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.