PDA

View Full Version : Problem with dependency on shared library and internal class



remizero
17th February 2017, 00:48
Hello again friends, this time I come here, with the following question:

I have the following project structure:


editor/
Editor.pro // is a subdirs project
Bin /
Bin.pro // is a subdirs project
com/
com.pro // is a subdirs project
Common /
Common.pro // is a subdirs project
Language /
Language.pro // is a subdirs project
Core /
Core.pro // is a share library project
Php /
Php.pro // is a share library project Depends on core.pro
Project /
Project.pro // is a share library project Depends on language.pro
Examples /
Examples.pro // is a subdirs project
Createproject /
Createproject.pro // Depends on project.pro

And the following are the respective configurations of the .pro files that I indicated in the previous structure:

Editor.pro

TEMPLATE = subdirs

SUBDIRS += \
bin \
com \
common \
examples

bin.depends = com
com.depends = common
common.depends = com
examples.depends = common

Common.pro

TEMPLATE = subdirs

SUBDIRS += \
actions \
addons \
codeeditor \
codegenerator \
files \
highlighter \
language \
project \
utils \
workspace

actions.depends = addons
addons.depends = actions files language project utils
project.depends = language
workspace.depends = codeeditor

Language.pro

TEMPLATE = subdirs

SUBDIRS += \
core \
php

php.depends = core

Core.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-02-12T18:09:20
#
#-------------------------------------------------

QT -= gui

CONFIG += c++11

greaterThan(QT_MAJOR_VERSION, 4): QT +=

TARGET = core
TEMPLATE = lib

DEFINES += CORE_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

SOURCES += Core.cpp \
model/ClassAbs.cpp \
model/MethodAbs.cpp \
model/ModelObj.cpp \
model/ParamAbs.cpp

HEADERS += Core.h\
core_global.h \
model/ClassAbs.h \
model/MethodAbs.h \
model/ModelObj.h \
model/ParamAbs.h

DESTDIR = ../

unix {
target.path = /usr/lib
INSTALLS += target
}

Php.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-02-12T18:09:45
#
#-------------------------------------------------

QT -= gui

CONFIG += c++11

greaterThan(QT_MAJOR_VERSION, 4): QT += xml xmlpatterns

TARGET = php
TEMPLATE = lib

DEFINES += PHP_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

DEPENDPATH += . ../core \
../../../com/ecosoftware/console \
../../utils \
../../project
INCLUDEPATH += . ../core \
../../../com/ecosoftware/console \
../../utils \
../../project

LIBS''= -L -lcore

SOURCES += Php.cpp \
controller/PhpDef.cpp \
controller/PhpLoadLanguage.cpp \
controller/PhpParser.cpp \
controller/PhpUtils.cpp \
model/Attribute.cpp \
model/Class.cpp \
model/Const.cpp \
model/PhpClassTypeModelAbs.cpp \
model/Restriction.cpp \
model/Trait.cpp \
model/Interface.cpp \
model/Method.cpp \
model/Param.cpp

HEADERS += Php.h\
php_global.h \
controller/PhpDef.h \
controller/PhpLoadLanguage.h \
controller/PhpParser.h \
controller/PhpUtils.h \
model/Attribute.h \
model/Class.h \
model/Const.h \
model/Param.h \
model/PhpClassTypeModelAbs.h \
model/Restriction.h \
model/Interface.h \
model/Method.h \
model/Trait.h

DESTDIR = ../

unix {
target.path = /usr/lib
INSTALLS += target
}

Project.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-02-12T18:33:25
#
#-------------------------------------------------

QT -= gui

CONFIG += c++11

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets xml xmlpatterns

TARGET = project
TEMPLATE = lib

DEFINES += PROJECT_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

DEPENDPATH += . ../language/core \
../language/php

INCLUDEPATH += . ../language/core \
../language/php

SOURCES += \
view/ProjectDlg.cpp \
controller/Manifest.cpp \
controller/ProjectBuilder.cpp \
model/Project.cpp

HEADERS +=\
project_global.h \
view/ProjectDlg.h \
controller/Manifest.h \
controller/ProjectBuilder.h \
model/Project.h

DESTDIR = ../

unix {
target.path = /usr/lib
INSTALLS += target
}

FORMS += \
view/ProjectDlg.ui

Examples.pro

TEMPLATE = subdirs

SUBDIRS += \
createproject

Createproject.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-02-13T12:14:49
#
#-------------------------------------------------

QT += core gui

CONFIG += c++11

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets xml xmlpatterns

TARGET = createproject
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

DEPENDPATH += . ../../common/project

INCLUDEPATH += . ../../common/project

LIBS''= -L../../common -lproject

SOURCES += main.cpp\
mainwindow.cpp

HEADERS += mainwindow.h

FORMS += mainwindow.ui


All this, for the following, if I build each library separately no problem, all compile.

But when I decide to compile createproject (which is a test executable) to test the correct execution of the code and the links to the libraries, I get the following error:


../../../../editor/common/language/php/model/Attribute.h:8:28: fatal error: model / ModelObj.h: No such file or directory
#include "model / ModelObj.h"
^
I have reviewed everything and from what I see, everything is fine, or so I think. Even if I build createproject without run command, if it compiles.

I'm working on
Debian 9 64bit
Qt 5.7.1
QtCreator 4.2.0

What can I be doing wrong? If you need any additional information let me know.

Thanks in advance for your answers and help.

anda_skoa
17th February 2017, 10:13
Does your INCLUDEPATH contain the directory that has the "model" directory as its child?

Cheers,
_

P.S: your Editor.pro has a circular dependency


com.depends = common
common.depends = com

remizero
17th February 2017, 16:33
Hi anda_skoa, thanks for your quick reply.

I apologize for not explaining this detail of relationship between libraries.

The php library depends on the core library within the subproject language. That's where the problem comes to me.

Answering your question, yes. As you can see in php.pro, in the INCLUDEPATH is the core library on which it depends, where the model directory is part of core.

Regarding the circular dependency, yes, I know that I have it, and I have to solve that inconsistency, but it's because I have a test code and implemented it directly in a project base class to test the operation and see how to decouple that section of code .

anda_skoa
18th February 2017, 12:51
You'll have to check the compiler invocation output, i.e. check if the -I directives include the path to the "core" directory.

Btw, your code snippets and your directory tree overview do not match, you Php.pro add "../core" but in your directory tree it is "../Core"

Cheers,
_

remizero
21st February 2017, 00:56
Hello anda_skoa, checking the code about your comment, because it is only a transcription error.

But I tell you something very curious and strange at the same time.

All the code that I put in the first post, was only a portion of all the code that I have programmed, only for purposes of my problem I reduced to those few files.

But the curious detail is that I took only the subprojects involved in the subproject project and language, to make use of them separately and test their operation and what was the surprise, which compiled and executed everything without problems.

What I can think of is that the problem is given by the cyclical dependence I have among the subprojects, which you referred to.


Com.depends = common
Common.depends = com

But at the same time it generates some noise, since in particular the project and language subprojects do not depend on the subproject com.

If you consider any other reason why this problem may occur, I would like to read your opinion.

Thanks in advance.

remizero
3rd March 2017, 14:03
Hello everyone.

Reacting the post, to comment that I have finally been able to solve the problem of dependencies between libraries that I have been presenting for some weeks that I decided to reorganize my project by subprojects and / or libraries.

To freshen up a bit, the problem came to me when my main application called a bookstore, but the latter in turn called another bookstore.

The solution that I have achieved after researching and studying the documentation of qmake, which did not guide me much, especially in the link between multiple dependencies of bookstores.

Well, to the point. The solution is given by the following considerations.

If a library or application needs a library, the documentation tells us to do the following, in the .pro of our library and / or application:


DEPENDPATH + =. /Path/to/my/lib1

INCLUDEPATH + =. /Path/to/my/lib1

LIBS + = -L /path/to/my/lib1 -llib1

But what happens if our library lib1, needs another library, say lib2, according to the documentation we should put:


DEPENDPATH + =. /Path/to/my/lib2

INCLUDEPATH + =. /Path/to/my/lib2

LIBS + = -L /path/to/my/lib2 -llib2

So far all "OK", but when we decide to do a test run, to verify the correct operation of our libraries, shows us the following error:


/Path/to/my/executable: error while loading shared libraries: lib2.so.1: can not open shared object file: No such file or directory

Here was where I lost in the documentation, because I did not get information related to this type of cases, and although, I got in huge amount of forums, information like this:


Export LD_LIBRARY_PATH = /path/to/root/installation/directory/lib/root/

He was not happy, considering that he could do everything from qmake, and indeed it is.

The only thing to do is to add the same lines in this case, from our lib1 library in our application and / or "top level" library, so the .pro of our application and / or "top level" Would be as follows:


DEPENDPATH + =. \
/Path/to/my/otherLibs \
/Path/to/my/lib2

INCLUDEPATH + =. \
/Path/to/my/otherLibs \
/Path/to/my/lib2

LIBS + = -L/path/to/my/otherLibs -lotherLibs \
-L/path/to/my/lib2 -llib2

And with this we have solved the problem of loading of shared libraries, or at least I have worked this way.

I hope I'm not making a mistake with this explanation, and if I'm wrong I'm open to criticism and / or advice.

In the same way, I hope it will help somebody else who has these same problems.

anda_skoa
4th March 2017, 13:17
Each library will usually have a ".pri" files (Qt project include) that adds the necessary elements to each variable.

The application then simply includes those and thus gets the full modification.

E.g. in your case, which apparently has headers and library in the source directory



INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
LIBS += -l$$PWD -lnameoflib


Cheers,
_