Qt C++:包含项目文件夹中的所有库文件

Posted

技术标签:

【中文标题】Qt C++:包含项目文件夹中的所有库文件【英文标题】:Qt C++: Include all library files in project folder 【发布时间】:2017-11-20 12:17:43 【问题描述】:

使用 Qt Creator,我创建了我自己的个人共享库,我目前正在从事的项目中使用该库。我想要做的是将 .so/.dll 文件放在应用程序的 lib/ 文件夹中,我在 .pro 文件中使用了以下代码:

LIBS += -L$$PWD/lib/

win32 
    SHARED_LIB_FILES = $$files($$PWD/lib/*.dll)
    for(FILE, SHARED_LIB_FILES) 
        BASENAME = $$basename(FILE)
        LIBS += -l$$replace(BASENAME,\.dll,)
    

unix 
    SHARED_LIB_FILES = $$files($$_PRO_FILE_PWD_/lib/*.so)
    for(FILE, SHARED_LIB_FILES) 
        BASENAME = $$basename(FILE)
        LIBS += -l$$replace(BASENAME,\.so,)
    

但是当我构建项目时,库文件中使用的函数出现以下错误:

Undefined reference to 'Class::function()'

如何动态包含 lib/ 文件夹中的库文件而不会遇到上述错误?

更新

编译器输出:

09:56:53: Running steps for project PocketList...
09:56:53: Configuration unchanged, skipping qmake step.
09:56:53: Starting: "/usr/bin/make" 
g++ -m64 -Wl,-O1 -o PocketList main.o combotonselect.o ComListaCodigos.o ComEditor.o ComRecordatorio.o ComControlador.o Aplicacion.o ComNota.o ComElidedLabel.o ComDashPad.o AppRecordatorios.o AppCodigos.o ComVinchero.o AppVincheros.o Mod.o AppDashboard.o ComLogger.o ComLlave.o ComListaNotas.o AppNotas.o VentanaPrincipal.o AppConvertidorMetrico.o qrc_res.o moc_combotonselect.o moc_ComListaCodigos.o moc_ComEditor.o moc_ComRecordatorio.o moc_ComControlador.o moc_Aplicacion.o moc_ComNota.o moc_ComElidedLabel.o moc_ComResizeImageDialog.o moc_ComDashPad.o moc_AppRecordatorios.o moc_Control.o moc_AppCodigos.o moc_ComVinchero.o moc_AppVincheros.o moc_Mod.o moc_ObservadorVincheros.o moc_AppDashboard.o moc_ObservadorCuota.o moc_ObservadorConexion.o moc_ComLogger.o moc_ComLlave.o moc_ComListaNotas.o moc_AppNotas.o moc_VentanaPrincipal.o moc_AppConvertidorMetrico.o moc_WorkerObservadorVincheros.o moc_WorkerObservadorCuota.o moc_WorkerObservadorConexion.o   -L/usr/X11R6/lib64 -L/media/omari/EXT/Programación/Qt\ Creator/PocketList/lib/ -lQt5Multimedia -lQt5Widgets -lQt5Gui -lQt5Network -lQt5Core -lGL -lpthread 
main.o: En la función `ConvertidorMetrico::cargar()':
main.cpp:(.text._ZN18ConvertidorMetrico6cargarEv[_ZN18ConvertidorMetrico6cargarEv]+0x9b0): referencia a `Controlador::leerFichero(QString)' sin definir
main.cpp:(.text._ZN18ConvertidorMetrico6cargarEv[_ZN18ConvertidorMetrico6cargarEv]+0xa49): referencia a `Controlador::split(QString, QString)' sin definir
main.cpp:(.text._ZN18ConvertidorMetrico6cargarEv[_ZN18ConvertidorMetrico6cargarEv]+0xda1): referencia a `Controlador::split(QString, QString)' sin definir
main.cpp:(.text._ZN18ConvertidorMetrico6cargarEv[_ZN18ConvertidorMetrico6cargarEv]+0xf0b): referencia a `Controlador::split(QString, QString)' sin definir
Makefile:292: fallo en las instrucciones para el objetivo 'PocketList'
main.cpp:(.text._ZN18ConvertidorMetrico6cargarEv[_ZN18ConvertidorMetrico6cargarEv]+0x1100): referencia a `Controlador::split(QString, QString)' sin definir
AppRecordatorios.o: En la función `AppRecordatorios::guardar()':
AppRecordatorios.cpp:(.text+0x21b3): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppRecordatorios.o: En la función `AppRecordatorios::cargarDatos()':
AppRecordatorios.cpp:(.text+0x2ea1): referencia a `Controlador::leerFichero(QString)' sin definir
AppRecordatorios.cpp:(.text+0x3297): referencia a `Controlador::split(QString, QString)' sin definir
AppCodigos.o: En la función `AppCodigos::actualizarCodigos()':
AppCodigos.cpp:(.text+0xecf): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppCodigos.cpp:(.text+0x124b): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppCodigos.o: En la función `AppCodigos::cargarDatos()':
AppCodigos.cpp:(.text+0x16be): referencia a `Controlador::esDirExistente(QString)' sin definir
AppCodigos.cpp:(.text+0x1919): referencia a `Controlador::leerFichero(QString)' sin definir
AppCodigos.cpp:(.text+0x1c6a): referencia a `Controlador::leerFichero(QString)' sin definir
AppCodigos.cpp:(.text+0x1e42): referencia a `Controlador::crearDirectorio(QString)' sin definir
AppCodigos.o: En la función `AppCodigos::eliminarCodigo()':
AppCodigos.cpp:(.text+0x2ef7): referencia a `Controlador::eliminarArchivo(QString)' sin definir
AppCodigos.o: En la función `AppCodigos::addCodigo()':
AppCodigos.cpp:(.text+0x3214): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppVincheros.o: En la función `AppVincheros::guardar()':
AppVincheros.cpp:(.text+0x1709): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppVincheros.o: En la función `AppVincheros::getCantidadVinchero(QString, QString)':
AppVincheros.cpp:(.text+0x1e02): referencia a `Controlador::getVinculosURL(QString)' sin definir
AppVincheros.o: En la función `AppVincheros::addVinchero()':
AppVincheros.cpp:(.text+0x3e4c): referencia a `Controlador::esUrlValido(QString)' sin definir
AppVincheros.cpp:(.text+0x3f14): referencia a `Controlador::leerURL(QString)' sin definir
AppVincheros.o: En la función `AppVincheros::actualizarVinchero()':
AppVincheros.cpp:(.text+0x4744): referencia a `Controlador::esUrlValido(QString)' sin definir
AppVincheros.cpp:(.text+0x479b): referencia a `Controlador::leerURL(QString)' sin definir
AppVincheros.o: En la función `AppVincheros::cargarDatos()':
AppVincheros.cpp:(.text+0x4ee0): referencia a `Controlador::leerFichero(QString)' sin definir
AppDashboard.o: En la función `AppDashboard::configurarObservadorConexion()':
AppDashboard.cpp:(.text+0x328f): referencia a `Controlador::existeFichero(QString)' sin definir
AppDashboard.cpp:(.text+0x3315): referencia a `Controlador::leerFichero(QString)' sin definir
AppDashboard.o: En la función `AppDashboard::actualizarCuotaObservada()':
AppDashboard.cpp:(.text+0x432f): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppDashboard.cpp:(.text+0x4f1e): referencia a `Controlador::eliminarArchivo(QString)' sin definir
AppDashboard.o: En la función `AppDashboard::solicitarCuota(bool)':
AppDashboard.cpp:(.text+0x5a9a): referencia a `Controlador::hayConexion()' sin definir
AppDashboard.o: En la función `AppDashboard::configurarObservadorCuota()':
AppDashboard.cpp:(.text+0x6747): referencia a `Controlador::existeFichero(QString)' sin definir
AppDashboard.cpp:(.text+0x67cc): referencia a `Controlador::leerFichero(QString)' sin definir
AppDashboard.o: En la función `AppDashboard::actualizarCuotaObservada(Control::Cuota*)':
AppDashboard.cpp:(.text+0x7d6a): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppDashboard.o: En la función `AppDashboard::setProxyConexion()':
AppDashboard.cpp:(.text+0x8c03): referencia a `Controlador::eliminarArchivo(QString)' sin definir
AppDashboard.cpp:(.text+0x921b): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppDashboard.o: En la función `Control::getCuota(QString)':
AppDashboard.cpp:(.text._ZN7Control8getCuotaE7QString[_ZN7Control8getCuotaE7QString]+0xc2): referencia a `Controlador::leerURL(QString)' sin definir
ComLlave.o: En la función `ComLlave::autenticar()':
ComLlave.cpp:(.text+0x10e8): referencia a `Controlador::cifrarContrasenna(QString)' sin definir
ComLlave.o: En la función `ComLlave::cargarDatos()':
ComLlave.cpp:(.text+0x154b): referencia a `Controlador::leerFichero(QString)' sin definir
ComLlave.o: En la función `ComLlave::cambiarContrasenna()':
ComLlave.cpp:(.text+0x3392): referencia a `Controlador::cifrarContrasenna(QString)' sin definir
ComLlave.cpp:(.text+0x371a): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
ComLlave.cpp:(.text+0x3a3c): referencia a `Controlador::cifrarContrasenna(QString)' sin definir
ComLlave.cpp:(.text+0x3ca0): referencia a `Controlador::leerFichero(QString)' sin definir
AppNotas.o: En la función `AppNotas::guardar()':
AppNotas.cpp:(.text+0x11f2): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppNotas.cpp:(.text+0x1b73): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
AppNotas.o: En la función `AppNotas::cargarDatos()':
AppNotas.cpp:(.text+0x217f): referencia a `Controlador::esDirExistente(QString)' sin definir
AppNotas.cpp:(.text+0x21dc): referencia a `Controlador::crearDirectorio(QString)' sin definir
AppNotas.cpp:(.text+0x25bd): referencia a `Controlador::leerFichero(QString)' sin definir
AppNotas.cpp:(.text+0x2cb9): referencia a `Controlador::leerFichero(QString)' sin definir
AppNotas.o: En la función `AppNotas::eliminarCuaderno()':
AppNotas.cpp:(.text+0x48b9): referencia a `Controlador::eliminarArchivo(QString)' sin definir
AppNotas.o: En la función `AppNotas::eliminarNota()':
AppNotas.cpp:(.text+0x4b34): referencia a `Controlador::eliminarArchivo(QString)' sin definir
AppNotas.o: En la función `AppNotas::addNota()':
AppNotas.cpp:(.text+0x53e7): referencia a `Controlador::escribirFichero(QString, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' sin definir
VentanaPrincipal.o: En la función `VentanaPrincipal::VentanaPrincipal(QWidget*)':
VentanaPrincipal.cpp:(.text+0x1015): referencia a `Controlador::esDirExistente(QString)' sin definir
VentanaPrincipal.cpp:(.text+0x15c7): referencia a `Controlador::crearDirectorio(QString)' sin definir
AppConvertidorMetrico.o: En la función `AppConvertidorMetrico::convertir(QString)':
AppConvertidorMetrico.cpp:(.text+0x3492): referencia a `te_interp' sin definir
AppConvertidorMetrico.cpp:(.text+0x3826): referencia a `te_interp' sin definir
moc_ObservadorVincheros.o: En la función `ObservadorVincheros::run()':
moc_ObservadorVincheros.cpp:(.text._ZN19ObservadorVincheros3runEv[_ZN19ObservadorVincheros3runEv]+0x28): referencia a `Controlador::hayConexion()' sin definir
moc_ObservadorVincheros.cpp:(.text._ZN19ObservadorVincheros3runEv[_ZN19ObservadorVincheros3runEv]+0x2fe): referencia a `Controlador::leerURL(QString)' sin definir
moc_ObservadorVincheros.cpp:(.text._ZN19ObservadorVincheros3runEv[_ZN19ObservadorVincheros3runEv]+0x5f7): referencia a `Controlador::getVinculosURL(QString)' sin definir
moc_WorkerObservadorVincheros.o: En la función `WorkerObservadorVincheros::process()':
moc_WorkerObservadorVincheros.cpp:(.text._ZN25WorkerObservadorVincheros7processEv[_ZN25WorkerObservadorVincheros7processEv]+0x28): referencia a `Controlador::hayConexion()' sin definir
moc_WorkerObservadorVincheros.cpp:(.text._ZN25WorkerObservadorVincheros7processEv[_ZN25WorkerObservadorVincheros7processEv]+0x2fe): referencia a `Controlador::leerURL(QString)' sin definir
moc_WorkerObservadorVincheros.cpp:(.text._ZN25WorkerObservadorVincheros7processEv[_ZN25WorkerObservadorVincheros7processEv]+0x5f7): referencia a `Controlador::getVinculosURL(QString)' sin definir
collect2: error: ld returned 1 exit status
make: *** [PocketList] Error 1
09:56:54: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project PocketList (kit: Linux)
The kit Linux has configuration issues which might be the root cause for this problem.
When executing step "Make"
09:56:54: Elapsed time: 00:01.

【问题讨论】:

在 Win32 上,您需要包含 .lib 而不是 .dll 链接器的信息存储在 Windows 上的 .lib 文件中。 dll 在运行时使用 但是我在 Linux 上遇到了同样的错误。 在 linux 上可能同样适用,除​​了 .lib.a 您是否尝试过在 Linux 上将库的路径添加到加载器的 LD_LIBRARAY_PATH 中? @nwp 不,在 Linux 上,您只有动态库 (.so) 和静态库 (.a)。在 Windows 上,您有动态库(.dll)、导入库(.lib.a)和静态库(.lib.a)。 MinGW工具链生成.a而不是.lib,但是用法是一样的。关键是在 Linux 上,您可以直接链接到动态库。 【参考方案1】:

您在 LIBS 中包含 lib(来自库文件名)。试试这个:

BASENAME = $$basename(FILE)
LIBNAME = $$replace(BASENAME, lib, )
LIBS += -l$$replace(LIBNAME,\.so,)

至少对于 unix,惯例是省略库文件名的 lib 前缀(例如 libname.so => -lname)

根据您发布的编译输出进行更新:

查看以g++开头的那行,你成功将lib目录提供给链接器

-L/media/omari/EXT/Programación/Qt\ Creator/PocketList/lib/ 

但未能通过库,因为我看到的只有那些:

-lQt5Multimedia 
-lQt5Widgets 
-lQt5Gui 
-lQt5Network 
-lQt5Core 
-lGL 
-lpthread

检查目录是否是其中一个,并且它包含所需的文件。 另外,在你的 pro 文件中使用 message() 函数来调试它。 例如:

message( LIBNAME )

【讨论】:

在 unix 部分,您将错误的名称传递给 LIBS。我将编辑答案以更好地解释这一点。 请从 qtcreator 发布您的编译输出。 不就是我必须在lib/文件夹中包含的.so文件吗? 您必须向链接器提供该 Controlador 类的定义。它在共享库中吗?如果是:该库在您的 lib 文件夹中吗?如果是,为什么您的 pro 文件无法将其添加到 LIBS 并且它没有显示在您的 g++ 行中?您是否按照我的建议使用 message() 函数进行检查? 是的,它是一个共享库,.so 文件在 lib 文件夹中,我添加了 message() 函数,但现在我无法更新编译器在我的问题中输出代码,因为它现在超过了问题字数限制。有什么我应该寻找的特定内容或我应该包括的输出的特定部分吗?

以上是关于Qt C++:包含项目文件夹中的所有库文件的主要内容,如果未能解决你的问题,请参考以下文章

Qt Creater中的.pro文件和.pri文件

Qt 资源文件利用率

如何使用 Qt Creator 将 C++ 头文件添加到 Qt 项目

更改后,QT QML资源文件不会重新编译

请教 如何运行含多个cpp的一个c++项目里面的一个cpp

qt creator 中如何使用c++库