c++ - 使用静态库编译时出现链接器错误

标签 c++ c++11 boost makefile static-libraries

<分区>

我有一个包含多个 .cpp 和 .h 文件的项目,我试图将源代码拆分为核心/通用内容和特定于应用程序的代码。基于此,我将代码文件分离到一个 Common 文件夹中,并将其编译为一个库。下面是该库的 Makefile:

CFLAGS=-std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib
SOURCES = $(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
OUTPUTFILE=libcommon.a

all: $(OUTPUTFILE)

$(OUTPUTFILE): $(OBJECTS)
    ar rcs $(OUTPUTFILE) $(OBJECTS)

.cpp.o:
    $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ $(GPROF)

clean:
    rm -f $(OBJECTS) $(OUTPUTFILE)

然后我创建了一个示例主文件,只是为了尝试使用该库编译应用程序。

这是主要源文件的代码:

#include "../Common/Functions.h"
#include "../Common/Logger.h"

int main() {
    Logger::Init(false, false);
    Logger::Debug("Test");
    string path = Functions::GetAppPath();
    Logger::Debug("App Path: ", path.c_str());
    return 0;
}

被引用的函数文件使用了 boost,这里是使用该库的应用程序的 makefile:

CC=g++
CFLAGS=-Wl,--verbose -std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib
LDFLAGS=-I../boost_1_57_0 -L../boost_1_57_0/stage/lib -L../boost_libs/lib -L/usr/lib64 -L/usr/kerberos/lib -L/usr/lib -L../Common
LIBS=-lz -lkrb5 -lk5crypto -lcom_err -lresolv -lm -lpthread -lrt -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -rdynamic -lcurl -lcommon
SOURCES = $(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=testApp
GPROF=-pg

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBS) $(GPROF)

.cpp.o:
    $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ $(GPROF)

clean:
    rm -rf *o $(OBJECTS)

当我尝试编译时,出现以下错误,提示对 boost 的 undefined reference :

g++  -Wl,--verbose -std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib main.cpp -o main.o -pg
g++ -I../boost_1_57_0 -L../boost_1_57_0/stage/lib -L../boost_libs/lib -L/usr/lib64 -L/usr/kerberos/lib -L/usr/lib -L../Common main.o -o testApp -lz -lkrb5 -lk5crypto -lcom_err -lresolv -lm -lpthread -lrt -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -rdynamic -lcurl -lcommon -pg
../Common/libcommon.a(Functions.o): In function `Functions::GetAppPath()':
/media/software/Robots/Common/Functions.cpp:43: undefined reference to `boost::filesystem::path::parent_path() const'
../Common/libcommon.a(Functions.o): In function `boost::filesystem::initial_path()':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:583: undefined reference to `boost::filesystem::detail::initial_path(boost::system::error_code*)'
../Common/libcommon.a(Functions.o): In function `boost::filesystem::system_complete(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:655: undefined reference to `boost::filesystem::detail::system_complete(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Functions.o): In function `unsigned short boost::date_time::month_str_to_ushort<boost::gregorian::greg_month>(std::string const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/date_time/date_parsing.hpp:67: undefined reference to `boost::gregorian::greg_month::get_month_map_ptr()'
../Common/libcommon.a(Logger.o): In function `Logger::Cleanup()':
/media/software/Robots/Common/Logger.cpp:84: undefined reference to `boost::thread::interrupt()'
../Common/libcommon.a(Logger.o): In function `Logger::InitFile(std::string, bool, std::_Ios_Openmode)':
/media/software/Robots/Common/Logger.cpp:186: undefined reference to `boost::filesystem::path::parent_path() const'
/media/software/Robots/Common/Logger.cpp:187: undefined reference to `boost::filesystem::path::parent_path() const'
../Common/libcommon.a(Logger.o): In function `Logger::Process()':
/media/software/Robots/Common/Logger.cpp:241: undefined reference to `boost::this_thread::interruption_point()'
../Common/libcommon.a(Logger.o): In function `boost::detail::thread_data_base::thread_data_base()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/pthread/thread_data.hpp:143: undefined reference to `vtable for boost::detail::thread_data_base'
../Common/libcommon.a(Logger.o): In function `boost::thread::start_thread()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:179: undefined reference to `boost::thread::start_thread_noexcept()'
../Common/libcommon.a(Logger.o): In function `boost::thread::~thread()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:254: undefined reference to `boost::thread::detach()'
../Common/libcommon.a(Logger.o): In function `boost::thread::get_id() const':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:741: undefined reference to `boost::thread::native_handle()'
../Common/libcommon.a(Logger.o): In function `boost::thread::join()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:767: undefined reference to `boost::thread::join_noexcept()'
../Common/libcommon.a(Logger.o): In function `boost::filesystem::exists(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:404: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Logger.o): In function `boost::filesystem::create_directories(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:523: undefined reference to `boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Logger.o): In function `boost::detail::thread_data<void (*)()>::~thread_data()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:90: undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
../Common/libcommon.a(Logger.o):(.rodata._ZTIN5boost6detail11thread_dataIPFvvEEE[_ZTIN5boost6detail11thread_dataIPFvvEEE]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
collect2: error: ld returned 1 exit status

不用说,整个项目编译没有问题。

这是我第一次尝试构建一个 C++ Linux 库并在另一个应用程序中使用它,所以我可能犯了一个菜鸟错误,所以请记住这一点。

非常感谢您的帮助。

谢谢。

最佳答案

命令行中库的顺序对链接器很重要。它从左到右处理库,根据当前库提供的任何函数解析已知的尚未解析的引用。

此外,这里特别相关的是,如果给定的库包含对它本身不提供的函数的引用,那么链接器不会根据它已经处理的库来解析这些函数。这就是为什么您有未解析的引用:您的库中最后有 -lcommon,因此其中的函数引用将仅针对 C 标准库进行解析。

在链接命令中多次列出库是有效的,有时这是需要的,但在这种情况下,我认为简单地将 -lcommon 作为第一个库而不是最后。这将解决问题。您甚至可以将其概念化为将与最接近它的主程序最密切相关的库放在链接命令中。

关于c++ - 使用静态库编译时出现链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37008820/

相关文章:

c++ - 为什么我会收到此 'enum' 不是类或命名空间错误?

c++ - 初始化数组 C++

c++ - 是否有使用运算符<<打印元组和对的合法方法?

c++ - 测试后无法取消 MPI 请求

c++ - 如何检查已安装的字体样式?

c++ - 使用 C++ 自动点击

c++ - 如何重置 shared_ptr?

c++ - 通过模板检查 c++11 中是否存在函数(不是方法)

c++ - boost 源代码

boost - 如何在 asio::buffer() 中使用 std::string