Unsolved Multi-library projects
-
I have an application that requires many libraries. I need to ensure that the libraries are built prior to the main executable, so they can be linked in. Some of the libraries have dependencies on other libraries, so they will need to have their dependencies built in advance as well.
How do I accomplish this effectively with Qt using .pro files and qmake? I have an implementation that works using a SUBDIRS project template, but I get build warnings that apparently no one else has ever seen, so I must be doing something wrong.
Thanks!
-
in linking the order of how you link is important. if you can share what types of errors you get we can investigate more into that.
-
@asanka424 Order is important because I found that Qt was not very good at figuring it out on its own, even with generated .prl files.
I have a SUBDIRS project which includes several subdirectories. Each has its own .pro file and produces a statically linked library.
CONFIG += c++11 ordered TEMPLATE = subdirs SUBDIRS += \ aop_logger \ aop_xml \ aop_serial \ aop_util \ aop_measure \ MoreMath \ MathUtilities \ DataCollection \ DebugLogger \ BufferedSharedMemory \ AvionicsBus \ AircraftDataModel \ WindModel \ TableLookups \ configuration \ AtosUtils \ dna \ aop_data \ aop_comm \ tap_data \ tap_messaging \ RouteContainer \ arinc_io_adapter \ aop_interface \ tap_display_app
The final subdirectory is the main application, which links in all the other libraries.
Here's an example of one of the sub-projects:
include(../top_srcdir.pri) QT -= core gui TARGET = aop_logger TEMPLATE = lib CONFIG += staticlib create_prl link_prl c++11 INCLUDEPATH += $$aop_logger_includes HEADERS += $$files($$aop_srcdir/core/aop_logger/*.hpp) SOURCES += $$files($$aop_srcdir/core/aop_logger/*.cpp) # target link libraries include(../ace_lib.pri) unix { target.path = $$PWD/lib INSTALLS += target }
So, starting from the root directory, which contains my top-level .pro file (the SUBDIRS project), i issue:
qmake -spec macx-xcode -recursive
When I do this, I get a warning for every sub-project:
WARNING: QMAKESPEC does not support multiple BUILDS
When I open up the project in Xcode, I have to manually select the main executable project each time, as it doesn't know what the main project is, but everything else seems to work.
-
@DRoscoe
Hello,Order is important because I found that Qt was not very good at figuring it out on its own, even with generated .prl files.
If you're building everything statically, as it seems to be the case from your example .prl-s are neither useful nor linked, since a static lib is a collection of translation units and nothing more. My advice, although unsolicited, is to start building your libraries dynamically instead of making one monster executable. Additionally, you don't seem to use Qt at all, only the
qmake
build system, is this correct, or is this only for the particular sub-project in question?Kind regards.
-
@kshegunov That's just for the particular sub-project. Almost all of the libraries are legacy from another project. The main app is heavily leveraged on Qt. I need to use the build system to create my Xcode project. The source tree supports Linux, Windows, MAC and iOS, so it doesn't make sense to version control project files from multiple build systems. We use CMake for everything but Mac/iOS
Your advice is indeed solicited. I am building for iOS which until recently only allowed static linking. I don't want to change that unless it clear that it would have an impact on the problem.
-
-
@kshegunov When I first started on this project I came across this blog. I may be mistaken, but it seemed to me that the ".depends" nomenclature was only valid for makefile-style projects. I am only using makefile-style projects for our Linux builds, so it didn't seem like a viable solution for generating my Xcode project file. Am I misunderstanding?
I did not realize that the .prl files did not help me with determining link dependencies. This article led me to believe it did. In fact, it seemed to me that this approach was ONLY valid for static libraries.
-
@DRoscoe said:
I am only using makefile-style projects for our Linux builds, so it didn't seem like a viable solution for generating my Xcode project file.
This should probably be answered by @SGaist or someone who actually uses macs for development, however as far as I understand the
qmake
build system it should be working independently of your IDE.I did not realize that the .prl files did not help me with determining link dependencies. This article led me to believe it did. In fact, it seemed to me that this approach was ONLY valid for static libraries
You seem to be correct and I - wrong, although the "link_prl" should appear in the application's project where the actual linking is performed, or at least this is how I understand the text you sourced.
-
Hi,
One thing I've been doing for some times now for ordered subdir projects is to follow this blog post. As for the development, I've essentially used the clang mkspec and I haven't had the problem mentioned by @DRoscoe.
-
@SGaist So you are saying that the ".depends" nomenclature works for iOS projects? When you say you are using "clang mkspec", what do you mean? You are not using "-spec macx-xcode"? So you are not generating an Xcode project? How then, are you able to sign and deploy iOS apps?
-
Yes it does, also for Android.
I'm using the default macx-clang mkspec to build OS X projects and for iOS, it's the macs-ios-clang by default (as in: you don't set it explicitly on the command line).
I use Qt Creator for development/deployment and it's working pretty well.
-
@SGaist Ok, thanks! The documentation really is poor in that regard. I came across several articles which basically said that ".depends" and that class of attributes was only for makefile-style projects. I am converting my project now and removing the ordered build. By specifying the dependencies in terms of subdirs, I am also hoping to eliminate the need for "-recursive" which I believe is causing the warnings I am seeing
-
@SGaist I have a follow-on question.
I have a pre-compiled library I need to link several of my other libraries to: ace_lib. When I compile the first project that needs it, I get the following error:
:-1: error: No rule to make target `ace_lib-make_first', needed by `sub-aop_logger-make_first'. Stop.
I am guessing it is giving me this error because it wants to BUILD ace_lib, but I don't want it to be built, but I DO want it to be recognized as a pre-existing library.
How can I do that? For informational purposes, here is my top-level project file
include(ace_lib.pri) #CONFIG += c++11 ordered CONFIG += c++11 TEMPLATE = subdirs SUBDIRS += \ aop_logger \ aop_xml \ aop_serial \ aop_util \ aop_measure \ MoreMath \ MathUtilities \ DataCollection \ DebugLogger \ BufferedSharedMemory \ AvionicsBus \ AircraftDataModel \ WindModel \ TableLookups \ configuration \ AtosUtils \ dna \ aop_data \ aop_comm \ tap_data \ tap_messaging \ RouteContainer \ arinc_io_adapter \ aop_interface \ tap_display_app aop_logger.depends = ace_lib aop_serial.depends = aop_logger aop_xml ace_lib aop_util.depends = aop_serial aop_measure.depends = aop_util MathUtilities.depends = MoreMath DataCollection.depends = MathUtilities AvionicsBus.depends = DebugLogger BufferedSharedMemory WindModel.depends = MoreMath configuration.depends = aop_serial aop_xml aop_util aop_measure aop_logger dna.depends = aop_xml aop_logger configuration aop_serial aop_util aop_measure AtosUtils aop_data.depends = aop_measure aop_util aop_serial aop_logger DataCollection \ TableLookups AvionicsBus WindModel AircraftDataModel aop_xml \ MoreMath MathUtilities aop_comm.depends = dna aop_data aop_measure aop_util aop_serial AvionicsBus tap_data.depends = aop_util aop_measure aop_serial aop_xml aop_data aop_logger \ TableLookups WindModel tap_messaging.depends = tap_data aop_serial aop_util aop_measure dna aop_xml aop_logger \ aop_comm aop_data arinc_io_adapter.depends = AvionicsBus aop_measure aop_util aop_serial aop_logger \ aop_data aop_interface.depends = AvionicsBus aop_comm dna aop_measure aop_util aop_serial \ aop_logger aop_data configuration aop_xml RouteContainer \ arinc_io_adapter tap_display_app.depends = tap_data tap_messaging aop_interface TableLookups WindModel
and here is the content of the ace_lib.pri file:
include (top_srcdir.pri) include (ace_path.pri) win32:CONFIG(release, debug|release): LIBS += -L$$SW_LIBRARY_PATH/ace/$$ACE_VER/lib/ -lACE else:win32:CONFIG(debug, debug|release): LIBS += -L$$SW_LIBRARY_PATH/ace/$$ACE_VER/lib/ -lACEd else:unix: LIBS += -L$$(ACE_LIB) -lACE win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$SW_LIBRARY_PATH/ace/$$ACE_VER/lib/libACE.a else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$SW_LIBRARY_PATH/ace/$$ACE_VER/lib/libACEd.a else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$SW_LIBRARY_PATH/ace/$$ACE_VER/lib/ACE.lib else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$SW_LIBRARY_PATH/ace/$$ACE_VER/lib/ACEd.lib else:unix: PRE_TARGETDEPS += $$(ACE_LIB)/libACE.a
-
.depends is only for other projects that must be built before. If you have a "link only" lib, I'd put it in a 3rdparty folder with a corresponding .pri file that you would include in the projects needing to link to that library.