Otherwise, things in the lib sub-directory weren't getting recompiled
even when lib/notmuch.h was changed.
The original rule we were using came from the GNU Makefile manual, but
only handled files in the current directory, not file in
sub-directories as we use here with our non-recursive Makefile.
So the .deps files being created were being put in the right place,
(such as .deps/lib/database.d), but the compiler was generating a
dependency for "database.o" rather than "lib/database.o" like we
want. We were already trying to do a sed job on that name to add a
dependency for the .d file as well. But the sed job was failing since
the expected pattern wasn't there, (the directory name was missing).
So the fix is simply to use basename to construct the search pattern,
and then use the name with the directory in the replacement (rather
than the back-reference).
Previously, the top-level Makefile was explicitly adding -I./lib to
the compiler flags. However, that's something that's much better done
from within the Makefile.local fragment within the lib directory
itself.
We were previously using separate CFLAGS and NOTMUCH_CFLAGS variables
in an attempt to allow the user to specify CFLAGS on the command-line.
However, that's just a lot of extra noise in the Makefile when we can
instead let the user specify what is desired for CFLAGS and then use
an override to append the things we require. So our Makefile is much
neater now.
I saw this recommendation in the implementation notes for "Recursive
Make Considered Harmful" and then the further recommendation for
implementing the idea in the GNU make manual.
The idea is that if any of the files change then we need to regenerate
the dependency file before we regenerate any targets.
The approach from the GNU make manual is simpler in that it just uses
a sed script to fix up the output of an extra invocation of the
compiler, (as opposed to the approach in the implementation notes from
the paper's author which use a wrapper script for the compiler that's
always invoked rather than the compiler itself).
The idea here is that every Makefile at each lower level will be an
identical, tiny file that simply defers to a top-level make.
Meanwhile, the Makefile.local file at each level is a Makefile snippet
to be included at the top-level into a large, flat Makefile. As such,
it needs to define its rules with the entire relative directory to
each file, (typically in $(dir)). The local files can also append to
variables such as SRCS and CLEAN for files to be analyzed for
dependencies and to be cleaned.
Instead of the old name of Makefile.dep. The idea being that the
user really doesn't need to see this by default, (and if debugging
the Makefile, the rules will make the name obvious).
We had originally copied this function in at a time when notmuch
wasn't actually depending on the GMime library. Now that it does,
we might as well call the function that exists there rather
than having a private copy of it.
This is based on the old notmuch-index-message.cc from early in
the history of notmuch, but considerably cleaned up now that
we have some experience with Xapian and know just what we want
to index, (rather than just blindly trying to index exactly
what sup does).
This does slow down notmuch_database_add_message a *lot*, but I've
got some ideas for getting some time back.
We want to start using this from both message.cc and thread.cc so we
need it in a place we can share the code. This also requires a new
notmuch-private-cxx.h header file for interfaces that include
C++-specific datatypes (such as Xapian::Document).
We've now got a new notmuch_query_search_threads and a
notmuch_threads_result_t iterator. The thread object itself
doesn't do much yet, (just allows one to get the thread_id),
but that's at least enough to see that "notmuch search" is
actually doing something now, (since it has been converted
to print thread IDs instead of message IDs).
And maybe that's all we need. Getting the messages belonging
to a thread is as simple as a notmuch_query_search_messages
with a string of "thread:<thread-id>".
Though it would be convenient to add notmuch_thread_get_messages
which could use the existing notmuch_message_results_t iterator.
Now we just need an implementation of "notmuch show" and we'll
have something somewhat usable.
I didn't notice this because `xapian-config -cxxflags` gives empty
output on my system. But for someone with the xapian library
installed in some non-standard location this would be important.
I didn't end up adding any of the warnings options that aren't allowed
for C++, (such as -Wold-style-definition, -Wnested-externs,
-Werror-implicit-function-declaration, -Wstrict-prototypes,
-Wmissing-prototypes, or -Wbad-function-cast). So for now we can
drop the separate C and C++ variables for warnings.
Having to enumerate all the enum values at every switch is annoying,
but this warning actually found a bug, (missing support for
NOTMUCH_STATUS_OUT_OF_MEMORY in notmuch_status_to_string).
When adding -Wextra we also add -Wno-ununsed-parameters since that
function means well enough, but is really annoying in practice.
So the warnings we fix here are basically all comparsions between
signed and unsigned values.
It's nice that Xapian provides a little function to print a textual
representation of the entire query tree. So now, if you compile
like so:
make CFLAGS=-DDEBUG_QUERY
then you get a nice output of the query string received by the query
module, and the final query actually being sent to Xapian.
This is important as we're using the message ID as the unique key
in our database. So previously, all messages with no message ID
would be treated as the same message---not good at all.
This is a fairly big milestone for notmuch. It's our first command
to do anything besides building the index, so it proves we can
actually read valid results out from the index.
It also puts in place almost all of the API and infrastructure we
will need to allow searching of the database.
Finally, with this change we are now using talloc inside of notmuch
which is truly a delight to use. And now that I figured out how
to use C++ objects with talloc allocation, (it requires grotty
parts of C++ such as "placement new" and "explicit destructors"),
we are valgrind-clean for "notmuch dump", (as in "no leaks are
possible").
This is in preparation for a new, public notmuch_message_t.
Eventually, the public notmuch_message_t is going to grow enough
features to need to be file-backed and will likely need everything
that's now in message-file.c. So we may fold these back into one
object/implementation in the future.
These were just little tests while getting comfortable with
GMime and xapian. I'll likely use pieces of these as notmuch
continues, but for now let's not distract anyone looking
at notmuch with these.
And the code will live on in the history if I need to look
at it.
Since we're currently just trying to stitch together In-Reply-To
and References headers we don't need that much sophistication.
It's when we later add full-text searching that GMime will be
useful.
So for now, even though my own code here is surely very buggy
compared to GMime it's also a lot faster. And speed is what
we're after for the initial index creation.
This is the beginning of the notmuch library as well, with its
interface in notmuch.h. So far we've got create, open, close, and
add_message (all with a notmuch_database prefix).
The current add_message function has already been whittled down from
what we have in notmuch-index-message to add only references,
message-id, and thread-id to the index, (that is---just enough to do
thread-linkage but nothing for full-text searching).
The concept here is to do something quickly so that the user can get
some data into notmuch and start using it. (The most interesting stuff
is then thread-linkage and labels like inbox and unread.) We can
defer the full-text indexing of the body of the messages for later,
(such as in the background while the user is reading mail).
The initial thread-stitching step is still slower than I would like.
We may have to stop using libgmime for this step as its overhead is
not worth it for the simple case of just parsing the message-id,
references, and in-reply-to headers.
Of course, there's not much that this program does yet. It's got
some structure for some sub-commands that don't do anything. And
it has a main command that prints some explanatory text and then
counts all the regular files in your mail archive.
This will (when it is finished) make a much more reliable way to
ensure that notmuch's sync program behaves identically to sup-sync.
It doesn't actually do anything yet.