|
libqi-api
2.0.6.8
|
go to the qi::path API reference.
The main idea of the qibuild-based project is that you always end up with the same layout.
For instance, right after having built you project, you end up with a directory looking like this:
Here we assume you have a foo executable which:
bar dynamic libraryfoo.data and XML files in a models directoryfoo.cfg
src
|__ foo
|__ data
| |__ foo.data
| |__ models
| |__ nao.xml
| |__ romeo.xml
|__ etc
|__ foo.cfg
build
|__ sdk
|__ lib
| |__ libbar.so
|__ bin
|__ foo
When everything is installed, you have something like:
prefix
|__ lib
| |__ libbar.so
|__ bin
| |__ foo
|__ share
| |__ foo
| |__ foo.data
| |__ models
| |__ nao.xml
| |__ romeo.xml
|__ etc
|__ foo
|__ foo.cfg
Here is a list of common requirements:
foo/foo.cfg, foo/foo.data and foo/models/*.xml in a clean, simple way, while making sure the solution works whereas the project is run from the build directory or installedfoo may need to write or update its configuration files or data but we need to make sure nothing will be written inside the installed directoryfoo.cfg files, we need to be able to process then in a correct order.Here is how it works:
/path/to/build/sdk, when something is installed, the prefix is the DESTDIR plus the installation prefix.foo.cfg is placed in build/sdk/foo/foo.cfg (same thing for data)argv0. For instance, if argv0 is /path/to/build/sdk/bin/foo, we can assume the prefix is /path/to/build/sdk.qi::path documentation.
The API of qi::path always make sure that:
For this to work, we must make sure that
Have a look on the API of qi::path for more details
Writing a configuration file is very different from reading one.
Let's assume the foo executable want to make sure that SPAM=42 in foo.cfg.
Here is how it works:
foo.cfg foo.cfg is foundfoo.cfg filefoo.cfg file.You can see that we ask for a list of paths when reading, but that we always write to one file.
Let's go through these steps again, assuming foo is installed in /usr/bin/foo, and foo.cfg in /usr/share/foo/foo.cfg, and that there is nothing else on the machine where foo is running.
foo.cfg using qi::path::getConfigurationPaths [~/.config/foo/foo.cfg, /usr/share/foo/foo.cfg] .config/foo/foo.cfg does not exist, we read /usr/share/foo/foo.cfg SPAM=42 to ~/.config/foo/foo.cfgThen each time a piece of code will ask for the foo.cfg path, it will get a list starting with ~/.config/foo/foo.cfg, so we are sure the setting SPAM=42 will be used.
/* * Copyright (c) 2012 Aldebaran Robotics. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the COPYING file. */ #include <iostream> #include <fstream> #include <vector> #include <qi/os.hpp> #include <qi/path.hpp> #include <qi/application.hpp> #include <qi/qi.hpp> int main(int argc, char *argv[]) { // Get the prefix name from argv0 // Performs various initializations. qi::Application app(argc, argv); // Get sdk prefix std::cout << "SDK prefix is: " << qi::path::sdkPrefix() << std::endl; // First argument is the name of the application, used // to build various paths later. std::string fooCfgPath = qi::path::findConf("foo", "foo.cfg"); if (fooCfgPath == "") { std::cerr << "Could not find foo.cfg" << std::endl; std::cerr << "Looked in: " << std::endl; std::vector<std::string > configPaths = qi::path::confPaths("foo"); std::vector<std::string>::const_iterator it; for (it = configPaths.begin(); it != configPaths.end(); ++it) { std::cerr << "\t" << *it << std::endl; } } else { std::cout << "Found foo.cfg: " << fooCfgPath << std::endl; std::cout << "Contents: " << std::endl; char buf[250]; std::ifstream ifs; // Set stream to the right charset ifs.open(fooCfgPath.c_str(), std::fstream::in); while (! ifs.eof()) { ifs.getline(buf, 250); std::cout << buf << std::endl; } ifs.close(); } // ... Write back the configuration to userCfgPath std::string userCfgPath = qi::path::userWritableConfPath("foo", "foo.cfg"); std::cout << "Writing config file to: " << userCfgPath << std::endl; std::ofstream ofs(userCfgPath.c_str(), std::fstream::out | std::fstream::trunc); ofs << "Hi, this is foo.cfg" << std::endl; ofs.close(); return 0; }
qi::path documentation.