Include C source files in a JUCE-Style module

I’d like to use SQLite in the implementation of a JUCE module I’m writing, hence in my my_module.cpp I’ve tried:

#include "sqlite3/sqlite3.h"
#include "sqlite3/sqlite3.c"

But compilation fails with several (expected) errors because SQLite is C code while I’m trying to compile it in a C++ file.
The errors I’m getting are about assignment of void* to other pointers, which apparently is allowed “as is” in C but require a formal cast in C++.

Any magic trick to circumvent the problem?

I’ve tried surrounding the whole section in extern "C" { } but that has no effect

1 Like

You can also add a my_module.c and include from there.

I’ve considered that, but:

  1. I don’t know if Projucer / CMake JUCE will do the right thing with that “my_module.c”, i.e. mark it for building with a C compiler

  2. Most importantly, my_module will also contain CPP files so its main files would end up being:

my_module.h
my_module.cpp
my_module.c

With my_module.h being something like:

#include "sqlite/sqlite.h"

#include "presets/PresetManager.h" // A class provided by the module, which uses sqlite3
// ... more .h containing declaration of more classes

Such a .h works fine when included by my_module.cpp, but because it contains classes declarations, it would fail miserably when included at the top of my_module.c

  1. It will.

  2. Wrap the C++ parts of your module header in #ifdef __cplusplus or don’t pull your module header into the c code. The my_module.c is just:

#include "sqlite3/sqlite3.h"
#include "sqlite3/sqlite3.c"

and then put

#include "sqlite3/sqlite3.h"

in the module header.

Here is an example of where I’ve done it:

2 Likes

Maybe this is redundant to what you’ve accomplished but this solution also has what you’re looking for:

Thank you both @jrlanglois and @RolandMR.
Regarding vflib, I don’t think it is maintained any more but the source code for the inclusion of sqlite can certainly be of inspiration.

For future reference to myself and to whoever is interested in doing the same, I confirm that it’s possible but with an important caveat:

in Visual Studio, by default the sources are compiled to objects with the following naming scheme:

my_module.cpp -> my_module.obj
my_module.c   -> my_module.obj

And as you can see there’s an obvious overwriting problem, which results in linker errors because the symbols from either the .cpp or the .c get obliterated when the other of the two files is compiled.

An elegant solution that I found is to convince Visual Studio to change its naming scheme for objects to:

my_module.cpp -> my_module.cpp.obj
my_module.c   -> my_module.c.obj

Which is obtained by setting
"C/C++" -> "Output Files" -> "Object File name"
to
$(IntDir)%(Filename)%(Extension).obj

as shown in the image below:

I wasn’t aware of their existence, but it appears there are more of those %(Macro) listed here: https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-well-known-item-metadata

P.S. in Xcode this doesn’t appear to be a problem because it is smart enough to realize that two sources would yield object files with the same name, and in that case it appends an unique string to both object filenames so they don’t clash, e.g.

my_module-57D8CCD34A81236B.o
my_module-67328B29CFDC53E.o

It may be easier to give them unique names such as mymodule_core.cpp and mymodule_util.c and then you don’t need to adjust compiler settings that’ll probably just get overwritten by the Projucer.

1 Like

Thank you for pointing this out. Especially because it made me reconsider what I now recognize a false assumption of mine.

I believed that, for a module named “my_module”, the module files were forced to have the same name with different extensions (“my_module.h”, “my_module.cpp”, “my_module.mm”, and, therefore, also “my_module.c”), and that any suffix added to that pattern could only be one of the “special” suffixes for e.g. platform or plug-in format ("_Linux", “_AAX”, etc.)

Now, re-reading the module specification, I realized that the suffix can be any, and only those specific suffixes are dealt with in a special manner. All the others are always compiled.

I think I’ll explicitly name that file “my_module_sqlite.c” and that’s it.
Thanks everyone

I’ll follow up on this just to note that the above change causes the build time to increase significantly, between 200% and 300% from some tests with Debug builds.

Yeah you read it right, it takes from two to three times longer to build when that setting is changed.

This side-effect is obviously unacceptable, therefore I’ll revert that change, but it’s also inexplicable to me… why should it cause such a slowdown? Could it be the presence of the %(Macros) ?