Reputation: 1778
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?
Upvotes: 1
Views: 606
Reputation: 181028
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
.
Upvotes: 2