如何在 autotools 项目(2017 年)中使用 Qt moc?

How to use Qt moc in autotools project (in 2017)?

尝试在 Linux.

上使用 autotools(我用它完成了很多项目)编译一个基本的 Qt 应用程序(Qt 的新手)

在链接开始之前,一切似乎都可以正常编译,这就是我得到以下结果的时候。

test-mainwindow.o: In function `MainWindow::MainWindow()':
mainwindow.cpp:5: undefined reference to `vtable for MainWindow'
mainwindow.cpp:5: undefined reference to `vtable for MainWindow'
mainwindow.o: In function `MainWindow::~MainWindow()':
mainwindow.cpp:11: undefined reference to `vtable for MainWindow'
mainwindow.cpp:11: undefined reference to `vtable for MainWindow'
mainwindow.o: In function `MainWindow::tr(char const*, char const*, int)':
mainwindow.h:10: undefined reference to `MainWindow::staticMetaObject'
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:415: test] Error 1

我以前没有做过 Qt 应用程序,所以我怀疑可能与 moc 有关,或者在我的 MainWindow Q_OBJECT header 中?我能在网上找到的大多数例子都是 4 岁以上。

这是我的源目录中的 Makefile.am 的样子。

include $(top_srcdir)/common.am

bin_PROGRAMS = test

test_SOURCES =               \
    main.cpp                 \
    mainwindow.cpp

test_CPPFLAGS = -I/usr/include -I/usr/local/include -I$(QT5_INCL) -I$(QT5_INCL)/QtWidgets -I$(QT5_INCL)/QtCore

test_LDFLAGS = -L/usr/lib64 -L/usr/local/lib64 -L/usr/local/lib -L$(QT5_LIBS)

test_LDADD = -lrt -lQt5Core -lQt5Gui -lQt5Widgets

如果我将其附加到 Makefile.am,我确定此时不完全正确...

moc-%.cpp: %.h
    /usr/lib64/qt5/bin/moc $(DEFINES) $(INCPATH) $< -o $@

moc-%.cc: %.h
    @MOC@ -o$@ $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MOC_CPPFLAGS) $<

ui-%.h: %.ui
    @UIC@ -o $@ $<

qrc-%.cc: %.qrc
    @RCC@ -o $@ $<

Automake 会在我尝试编译之前抱怨这个...

Makefile.am:19: warning: '%'-style pattern rules are a GNU make extension
Makefile.am:24: warning: '%'-style pattern rules are a GNU make extension
Makefile.am:27: warning: '%'-style pattern rules are a GNU make extension
Makefile.am:30: warning: '%'-style pattern rules are a GNU make extension

有人知道如何使用 autotools 实现 moc 部分吗?

Automake 不会自动识别您的程序依赖于需要通过使用 moc 或其他 Qt 工具处理其他文件来创建的未指定源。您的 *_SOURCES 变量需要明确命名此类派生源,并且您需要提供文字 make 规则或构建它们的规则。

您可能还需要在 BUILT_SOURCES 变量的值中命名其中的一些。 C++ 顶级源文件不太可能需要这种处理,但构建的头文件(或在 #include 指令中命名的任何其他源文件)很可能需要它。

细节有点取决于你,我不能提供具体的解决方案,因为不清楚你的确切需求是什么。但是所需的 Automake 文件可能看起来像这样的东西:

include $(top_srcdir)/common.am

bin_PROGRAMS = test

# headers that must be processed with moc to generate C++ source files
test_qtheaders = mainwindow.h

# the source files that will be generated via moc.  The string "_moc" is inserted
# to, hopefully, avoid name collisions
test_moc_sources = $(test_qtheaders:.h=_moc.cpp)

test_SOURCES =               \
    main.cpp                 \
    mainwindow.cpp           \
    $(test_moc_sources)

test_CPPFLAGS = -I/usr/include -I/usr/local/include -I$(QT5_INCL) -I$(QT5_INCL)/QtWidgets -I$(QT5_INCL)/QtCore

test_LDFLAGS = -L/usr/lib64 -L/usr/local/lib64 -L/usr/local/lib -L$(QT5_LIBS)

test_LDADD = -lrt -lQt5Core -lQt5Gui -lQt5Widgets

# A traditional-style Make suffix rule for generating *_moc.cpp files from *.h
# files via moc.  For the former (especially) to be recognized as a suffix,
# you need to tell Automake about it via the `SUFFIXES` variable.
# The mkdir is present to support out-of-source building.
# Assumes that the MOC variable will be set by configure.
.h_moc.cpp:
    $(MKDIR_P) `dirname $@`
    $(MOC) -o $@ $(test_CPPFLAGS) $(CPPFLAGS) $<

SUFFIXES = .h _moc.cpp

您可能还想在 CLEANFILES 中列出构建的源代码,否则当您 make clean.

时它们将被遗忘