Managing data¶
The problem¶
Let’s assume the foo
executable needs a file named foo.dat
You may want to put foo.dat
under version control, and have the foo
executable
find the foo.dat
file when run:
- from the build dir
- when installed
The solution¶
Here is a possible solution, assuming you have the following layout:
<worktree>
foo
CMakeLists.txt
main.cpp
share
foo
foo.dat
# in CMakeLists.txt
qi_create_bin(foo main.cpp)
# mark this directory as a potential prefix for
# qi::path::findData()
qi_stage_dir()
# create an install rule for foo.dat:
qi_install_data(share/foo/foo.dat SUBFOLDER foo)
// in main.cpp
#include <qi/application.hpp>
#include <qi/path.hpp>
int main(int argc, char* argv[])
{
// Mandatory for qi::path to work:
qi::Application app(argc, argv);
std::string fooPath = qi::path::findData("foo", "foo.dat");
}
How it works¶
When run from the build dir¶
The constructor of qi::Application
starts by figuring out the exact path
of the binary currently running.
(For instance, /path/to/build/sdk/bin/foo
).
It then sets the SDK prefix to /path/to/build/sdk
, then tries to parse
the path.conf
in /path/to/build/sdk/share/qi/path.conf
.
Every path in this file is added to the list of possible SDK prefixes, recursively.
The path.conf
is generated by qibuild configure
and contains paths
to every possible SDK prefix (the <build/sdk>
folder for every project in the
worktree, and the path to every package in the toolchain).
Then qi_stage_dir()
can find out the directory of the CMakeLists.txt
it was
called from, and add it at the top of the path.conf
file.
When installed¶
When installed, say to /tmp/foo
, the SDK prefix will be /tmp/foo
, and
since everything is installed to the same destination, qi::path::findData()
will
find foo.dat
in /tmp/foo/share/foo/foo.dat