Почему qmake помещает все объекты (.o) в один каталог?
Скажем, у меня есть приложение Qt, где у меня есть два класса с одинаковым именем в двух разных пространствах имен:
namespace namespace1
{
class SomeClass;
}
namespace namespace2
{
class SomeClass;
}
и у меня есть структура каталога проекта в соответствии с ним:
-->src/
-->namespace1/
-->someclass.cpp
-->namespace2/
-->someclass.cpp
Когда я компилирую приложение с qmake, он помещает все файлы объектов (.o) в один каталог - поэтому он сначала создает файл someclass.o, а затем перезаписывает его со второй someclass.o - это столкновение имен, так что это плохо.
Почему qmake не учитывает структуру каталогов исходных файлов и почему он не создает что-то вроде namespace1_someclass.o и namespace2_someclass.o?
Да, я могу поместить мои классы в один каталог и называть их namespace1_someclass.cpp и namespace2_someclass.cpp, и не будет конфликтов имен, но это вызывает небольшие неудобства глядя на исходные файлы в обозревателе проектов в Qt Creator, потому что, когда в проекте много исходных файлов, это гораздо менее читаемо, чем если бы была структура каталогов, которую я могу развернуть или свернуть.
Еще одна крайность заключается в том, чтобы структура каталогов была такой:
-->src/
-->namespace1/
-->namespace1_someclass.cpp
-->namespace2/
-->namespace2_someclass.cpp
который решает конфликт имен, но он дублирует дубликаты имен имен и, следовательно, снова становится менее читаемым.
Почему qmake не имеет по крайней мере опции поместить объектные файлы в структуру каталогов в соответствии с исходными файлами? Создатели Qt не видят, что это важная функция?
И еще одно: вы могли бы порекомендовать мне использовать cmake инструмент вместо qmake, но я вижу, что использование cmake намного сложнее, чем qmake и qmake делает свою работу превосходной для меня до сих пор - кроме размещения объектных файлов.
Ответы
Ответ 1
Фактически вы можете помещать объектные файлы вместе с исходными файлами, используя:
CONFIG += object_parallel_to_source
или
CONFIG += object_with_source
в зависимости от вашей версии qmake.
Источник: https://wiki.qt.io/Undocumented_QMake#Config_features
Ответ 2
В зависимости от того, что вы пытаетесь построить, вы можете использовать шаблон subdirs
в qmake для этого. Вам нужно будет поместить файл проекта в каждый из ваших namespace
каталогов, и в этом вы можете указать разные директории вывода для ваших объектных файлов.
-->src/main.pro
-->namespace1/n1.pro
-->someclass.cpp
-->namespace2/n2.pro
-->someclass.cpp
main.pro
:
TEMPLATE = subdirs
SUBDIRS = namespace1 namespace2
n1.pro
и n2.pro
:
include("../common.pri")
OBJECTS_DIR = $${PWD}
TARGET = some_target
TEMPLATE = some_qmake_template
common.pri
: конфигурации, общие для обоих проектов.
Ответ 3
Относительно ваших опасений, что CMake
может быть слишком сложным: я работал над проектами, использующими обе системы сборки. Хотя я согласен с тем, что qmake
, вероятно, проще начать, CMake
тоже имеет свои достоинства:
-
Это делает сборку вне источника очень простой. Просто выполните cmake <Path to source>
в своем каталоге сборки. Это здорово, когда ваши источники находятся на общем ресурсе NFS, и вы хотите, чтобы объектные файлы размещались в локальной файловой системе.
-
Его поддержка поиска дополнительных библиотек очень эффективна. Многие файлы FindXXX.cmake
уже отправлены с вашим дистрибутивом CMake
, что делает включение "тяжелых" библиотек, таких как OpenCV
, как легко, как FIND_PACKAGE(OpenCV REQUIRED)
.
-
У него даже есть готовая поддержка для Qt
. Фактически, я использую его для более крупного программного проекта, где Qt
используется для части GUI. Мы решили CMake
, потому что нам нужна независимость от платформы и несколько библиотек, которые мы не могли легко добавить через qmake
.
В целом, с помощью системы сборки вам удобнее (пока ваша система сборки не препятствует разработке вашего программного обеспечения).