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:
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");
}
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, 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