One of the many big advantages to using C++ for applications and projects is the access one has to the vast library of C++ libraries and frameworks available. Basically, there is a C++ library for anything, and if there isn’t, there is definitely a C library for it.
Back in the day, it was generally a challenge to integrate different libraries into C++ projects due to the variances in compatibility between different C++ compilers. A project built with GCC would have trouble compiling on VC++, and a project built with VC++ would have trouble compiling on BCC, etc. Thankfully, we’ve come a long way since those days and C++ compiler now have a substantial level of compatibility with each other.
C++Builder’s use of CLANG is no exception to this. While the classic compiler often has issues with modern C++ syntax, the CLANG compiler is one of the most standards compliant C++ compilers available, and as such, opens up the vast universe of C++ libraries to your C++Builder projects.
This doesn’t mean to say that it’s trivial. There are always some tricks and tweaks one must do to use any library in your projects, but in comparison to what was necessary before, it’s dead easy.
In this blog post, we’ll explore what it takes to get a fairly common C++ library, SQLiteCpp, working in a C++Builder project.
Table of Contents
What is SQLiteCpp
SQLiteCpp is a C++ RAII wrapper around the sqlite database C library, providing an excellent C++ interface to this almost universal portable relational database library.
Sqlite is used in many different applications ranging from embedded projects to mainstream applications as an easy-to use integrated database for storing, querying and retrieving data of many different types.
We’ll use SQLiteCpp to create a simple application that stores and retrieves some data inside a simple console application in C++Builder.
Getting the Library
SQLiteCpp is hosted on Github and the repository includes all the files necessary to compile into your application.
1. Go to https://github.com/SRombauts/SQLiteCpp
2. Download the latest release and extract it into a folder
Setting up the Projects
SQLiteCpp supports the CMake build system, so we could use that to build our libraries with C++Builder, but it’s often more interesting and direct to just create the projects yourself. This has the added advantage that you can customize the build to suit your use.
3. Create a directory inside the extract folder called cbuilder. This will contain our C++Builder-specific project files. The resulting directory structure should look like this:
4. We want to build this library as a static library that we can link into our C++Builder application, so go to RAD Studio and create a new static library project. Save this project as sqlitecpp.cbproj inside the cbuilder directory.
5. Go into the Project Options and enable the CLANG compiler for all configurations:
6. Go to the Librarian settings and set the Page Size to 64 (this is based on experience – if you don’t know the page size to use, the TLIB linker will tell you whether the page size needs to be adjusted when you build the project)
Selecting the Source Files
Now that we have our project set up, we need to add the necessary source files into the project to be compiled. The way to determine which files to include differs for each project, and it sometimes requires some digging to determine the right files. CMakeLists.txt can definitely help with this. The following guidelines should help:
- Look for a src directory, files with a .c, .cpp or .cxx extension will be the source files
- Ignore files that contain a main() method. These are generally test, demo or example files that are intended to be standalone applications.
For SQLiteCpp, these are the source files:
- sqlite3/sqlite3.c
- src/Transaction.cpp
- src/Backup.cpp
- src/Column.cpp
- src/Database.cpp
- src/Exception.cpp
- src/Statement.cpp
7. Add these files to the library project.
Building the Library
If you were to try to build this library right now, you’d get some errors similar to the following:
We need to update some project options and set some include paths.
8. Set the include path. You may have noticed that the project has an include directory that’s at the same level as the src files. Add this folder to the project include path so that the headers can be found:
9. Build the project. It should complete successfully. Congratulations, you now have your SQLiteCpp library.
Using the Library
Now that we have our library, we can create a simple application to test it out.
10. Create a new C++ console application in the same project group. Choose the Visual Component Library as the framework for the console application so we can see this library working with the VCL.
11. Save this project as test_sqlite.cbproj in the cbuilder folder.
12. Go into the Project Options for this project and add ..include as an include path for this project and enable the CLANG compiler, just like we did for the SQLiteCpp library.
13. Add in the include paths into the top of the C++ file in our test project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <vcl.h> #include <windows.h> #pragma hdrstop #pragma argsused #include <tchar.h> #include <stdio.h> #include <conio.h> #include <SQLiteCpp/SQLiteCpp.h> #pragma link "sqlitecpp.lib" int _tmain(int argc, _TCHAR* argv[]) { return 0; } |
Note that we used the #pragma link directory to tell the compiler that we need to link the sqlitecpp.lib library from the library project. You can alternatively just add the .lib file to the test project, but using #pragma link can make this simpler.
14. Now add some code to create a database, insert some data and read it back out again:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
int _tmain(int argc, _TCHAR* argv[]) { // Open a database file in create/write mode SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); std::cout << "SQLite database file " << db.getFilename().c_str() << "n"; // Create a new table with an explicit "id" column aliasing the underlying rowid db.exec("DROP TABLE IF EXISTS test"); db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"); // first row db.exec("INSERT INTO test VALUES (NULL, "test")"); // second row db.exec("INSERT INTO test VALUES (NULL, "second")"); // update the second row db.exec("UPDATE test SET value="second-updated" WHERE id='2'"); // Check the results : expect two row of result SQLite::Statement query(db, "SELECT * FROM test"); std::cout << "SELECT * FROM test :n"; while (query.executeStep()) { std::cout << "row (" << query.getColumn(0) << ", "" << query.getColumn(1) << "")n"; } getch(); return 0; } |
15. Finally, run the project to compile it and see the library in operation:
Final Thoughts
As this simple exercise has demonstrated, C++Builder with the CLANG compiler opens up a world of possibilities for the different libraries and frameworks that can be integrated into your projects. We didn’t have to make a single code change to get this open-source C++ library to compile and work in our C++Builder applications.
There are thousands of other C++ projects out there and I can strongly encourage you to experiment with using them in your C++ projects!
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition