I have found a solution which involves two top-level SUBDIRS projects, one "app" project (i.e. with "TEMPLATE = app"), and three "TEMPLATE = lib" subprojects.
It's actually quite possible to put the app project file in the same folder as the top-level SUBDIRS project if you use the .file syntax on the target dependencies.
Here is the directory structure, similar to my other post above, but a little different:
TOP_Project_Dir
|__3rd_party
|__A
|__src
|__A_lib.hpp
|__A_lib.cpp
A_lib.pro
|__B <== (similar to A)
|__C <== (similar to A)
Libs.pro
.qmake.conf
|__app
|__lib
|__src
App.pro
Project.pro
.qmake.conf
|__build
|__Project
|__Qt-<version>
|__Debug
|__Release
Here is the top-level Project.pro file:
TEMPLATE = subdirs
SUBDIRS = Libs App
lessThan(QT_MAJOR_VERSION,6):CONFIG+=ordered
APP_DIR = $$top_srcdir
THIRD_DIR = $$clean_path($${APP_DIR}/../3rd_party)
Libs.file = $${THIRD_DIR}/Libs.pro
App.file = $${APP_DIR}/App.pro
App.depends = Libs
The Libs.pro file:
TEMPLATE = subdirs
SUBDIRS = \
A/A_lib.pro \
B/B_lib.pro \
C/C_lib.pro
Here it was more convenient to just refer directly to the file paths in the SUBDIRS section.
The A_lib.pro file (and almost exactly the same for B and C libraries):
CONFIG -= qt
TEMPLATE = lib
CONFIG += static c++17 release
SOURCES += \
src/A_lib.cpp
HEADERS += \
src/A_lib.hpp
TARGET = A
PROJECT_DIR = $$clean_path($${top_srcdir}/../)
APP_DIR = $${PROJECT_DIR}/app
DESTDIR = $${APP_DIR}/lib
Finally, the App.pro file:
CONFIG -= qt
TEMPLATE = app
TARGET = MyApp
CONFIG += c++17 console
APP_DIR = $${top_srcdir}
LIB_DIR = $${APP_DIR}/lib
SRC_DIR = $${APP_DIR}/src
THIRD_DIR = $$clean_path("$$top_srcdir/../3rd_party")
OBJECTS_DIR = $${top_builddir}/.obj
MOC_DIR = $${top_builddir}/.moc
RCC_DIR = $${top_builddir}/.qrc
UI_DIR = $${top_builddir}/.ui
DESTDIR = $${top_builddir}/exec
SOURCES += $${SRC_DIR}/theApp.cpp
LIBS += -L"$${LIB_DIR}" -lA -lB -lC
INCLUDEPATH += \
$${THIRD_DIR}/A/src \
$${THIRD_DIR}/B/src \
$${THIRD_DIR}/C/src
Here is the source of A_lib.hpp and A_lib.cpp which is about the same for B and C:
// A_lib.hpp
#ifndef A_HPP
#define A_HPP
namespace A {
void whoAmI();
}
#endif
// A_lib.cpp
#include "A_lib.hpp"
#include <iostream>
namespace A {
void whoAmI() {
using namespace std;
cout << "I'm in A lib" << endl;
}
}
Finally, theApp.cpp file:
#include "A_lib.hpp"
#include "B_lib.hpp"
#include "C_lib.hpp"
int main() {
A::whoAmI();
B::whoAmI();
C::whoAmI();
}
In the Qt Creator "Default Build Properties" under "Build & Run", I have this template set for the default build directory:
../build/%{Project:Name}/Qt-%{Qt:Version}/%{BuildConfig:Name}
This gives me for my little project this build directory in Debug mode:
$HOME/code/TOP_Project_Dir/build/Project/Qt-5.15.13/Debug
This is nice because "TOP_Project_Dir/3rd_party" and "TOP_Project_Dir/app" are under source-code management ("SCM", I am using Fossil for the real project) but in two different repositories, and everything under "build" gets ignored.
The information @KH-219Design and @SGaist gave me was important to making this work. The sticking point, though, was that both of the top-level .pro files with TEMPLATE=subdirs needed to be parallel to each other, i.e. at the same level relative to the TOP_Project_Dir folder. These also need to be under SCM, so if one was on a different level, the build output of one would have gotten in the way of the other.
Marking this now as SOLVED!