Trying to compile a basic Qt application (new to Qt) with autotools (which I've done many projects with) on Linux.
Everything seems to compile fine until the linking starts, and thats when I get the following results.
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
I've not done a Qt app before, so I suspect maybe something to do with the moc, or Q_OBJECT in my MainWindow header? Most all examples I could find online are 4+ years old.
Here's what the Makefile.am in my source dir looks like.
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
And if I append this to the Makefile.am, which I'm sure isn't fully correct at this point ...
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 will complain w/ this before I even try to compile ...
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
Anyone have ideas about how to implement the moc part of things using autotools?
Automake does not automatically recognize that your program depends on unspecified sources that need to be created by processing other files with moc
or other Qt tools. Your *_SOURCES
variables need to name such derived sources explicitly, and you need to provide a literal make
rule or rules for building them.
You may furthermore need to name some of those in the value of the BUILT_SOURCES
variable. C++ top-level source files are unlikely to need this treatment, but built header files (or any other sources named in an #include
directive) very likely do need it.
The details are somewhat up to you, and I cannot offer a specific solution because it's unclear what your exact needs are. But the desired Automake file might look something like this:
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
You may also want to list the built sources among your CLEANFILES
, else they will be left behind when you make clean
.