Location of config files in project c++ - c++

I was wondering whether there is a convention for storing config files in c++. At the moment I am storing the config files in the same directory as the source code that uses them. When building I make sure via the CMakeLists to copy them to the correct location so I can just access them in a relative way (e.g. "config.cfg" iso "/foo/bar/config.cfg) for convenience.

The practice for config files is non portable and operating system dependent. You have also to ask yourself if your configuration is defined per installation/system or per user.
In general, it is a very bad idea to store config in the same directory as your execuable, at least once the developpement is finished. In general executables may be shared between several users and should therefore for security reasons be located in directories that are write-protected for everybody but the system administrator.
For unix/linux, you could for example consider:
/etc or a subfolder thereof, if your configuration is per installed system,
~/ if it's user defined configuration. The usual practice would be to start the filename with a dot. This article will tell you more.
For windows systems, you should consider:
the usual approach now, goes to the registry. Of course, this uses the windows api and is fully non portable.
a subfolder of C:\ProgramData or C:\Users\All users\AppData\Local if your configuration is per installed system,
a subfolder of C:\Users\%USERNAME%\AppData\Local for the users's own configuration.
This SO questions shows how to find the right folders.

Related

Is it possible to edit the hardcoded path in a Windows (custom built) installation of Qt 5?

We are building Qt 5.10 internally, and installing it to a given prefix on the build environments.
We would like to be able to relocate the installation (notably, but not only for, distribution). We are aware of qt.conf, as pointed out by this answer.
Yet, is there a maintained way to directly edit the values of those hardcoded paths in the installed files?
EDIT:
More rationale behind why we thing qt.conf is inferior to directly patching the binaries.
On development machines, it means that instead of simply patching the installed binaries once, we have to provide a configuration file in each folder containing an application depending on Qt.
Even worse than that, we discovered through failures (and the help of this post) that qtwebengineprocess.exe, in qtprefix/bin, expects its own qt.conf file, otherwise it will use the paths hardcoded in the libraries. This means that we have to touch the the library folder anyway, in otder to edit the configuration file to make it match the folder location on each development machine.

How to change the tmp directory location in ember apps

Is there a way to change the location of the tmp directory ember-cli is using to process trees? (without using symlinks)
I am trying to develop an ember app using a linux VM on a windows host. Shared folders of any type (be it virtualbox shared folders, nfs or smb) are slow, don't allow symlinks and ember-cli produces a lot of files in the tmp directory. Being able to move this tmp to the native filesystem of the VM would help a lot.
This should be easily configurable, but i couldn't find any configuration option that would allow it.
No. Nobody answered and the help of the ember-cli build doesn't show that parameter.
How about creating a RAMDisk and hardlinking your project tmp folder to it? In Windows this can be done as follows:
Create RAM DISK with imdisk
mklink /j "C:\project\tmp\" "H:\ember-tmp" where C:\project is your local project folder and H: is your RAM Disk.
I'm afraid I don't know the Linux equivalents but it should be easy enough to find. Apparently this can roughly halve your build times with no chance of losing data.
Information sourced from https://emberjs-developer.quora.com/How-to-make-Ember-js-CLI-ember-s-32-times-faster and kudos to Stefan Penner for the suggestion.
Note the link folder MUST already exist before you run mklink otherwise you get the misleading message "Local volumes are required to complete the operation" and the link destination (junction folder) MUST NOT exist otherwise you get the message "Cannot create a file when that file already exists".
Note as of Ember 3.0 you can now change the cache by doing the below
BROCCOLI_PERSISTENT_FILTER_CACHE_ROOT=/path/to/my/other/tmp/
This will output the broccolli files to the path of your choosing. You will need to do the tidy up operation yourself on this custom path
More information here
https://github.com/stefanpenner/async-disk-cache/issues/35

Running a process inside a virtual file system?

What I'm trying to achieve is to run a program, which thinks a folder exists within its own folder while actually the folder is somewhere else on the system.
So my program would launch a process and say to the process: Folder A which is at C:\A is within your own directory at C:\Program Files (x86)\SomeProgram\A
So the "virtual" directory would only be visible to that process.
I'm using Qt to program my program, so if there are any Qt functions I could use that would be great (in relation to portability). However, plan C++ or any windows-bound API's would be fine.
I was thinking about NTFS junctions or symbolic links but I would have no idea how to create either of those in C++, let alone bind them to a specific process.
Thanks in advance!
EDIT:
In relation to the above, I've found this question: https://superuser.com/questions/234422/does-windows7-support-symbolic-links-folder-shortcuts. However, it only shows how to perform the required actions from the command-line and it wouldn't be process bound.
EDIT 2:
Some extra information: I'm trying to create a virtual directory that is made up of a couple of other directories but then merged (I'm using a priority system to decide which files "win" from other files). These merged directories would then appear to the target process as one directory containing the merged files.
I think I'm going to stick with Window's mklink command. It seems to suit my needs the best.
What I'm going to do is use QFile::link() on all operating systems that aren't Windows, and QProcess with mklink on windows. This should work on every operating system.
For a good example look here: https://stackoverflow.com/a/21013935/979732
Such tasks are accomplished by use of a filesystem filter driver. The driver intercepts OS requests going to the filesystem and lets you insert your own virtual files and directories into the existing directory on the disk. Filter driver can be an overkill for your particular task, though.
Detours approach mentioned in comments requires system-wide hooking of file APIs and will slowdown the whole system(filesystem filter driver is attached to one disk and it's a documented approach, so it's faster and more robust).

Is there a special place to store configurations in standard c++

Is there a standard place to store configurations like database setting in c++? Just use xml file?
Need windows solution, but it is better to be platform independent.
Check out Boost Program Options. Apart from being one of the best command-line option processors in any language, it also supports reading configuration data from files with a syntax like INI, and using environment variables. It's suitable for exactly what it says: program options. If you have a huge variety or a hierarchy of configurations, however, you might better check out Boost Property Tree, which read INI files but also XML or JSON, and is probably better suited if you have a really large configuration.
No standard that I know of, but you have several libraries for program configuration, for example libconfig. Also, the Windows API has some utilities to parse INI files for programs, for example see this link.
Standard C++ is a language only, it don't know anything other than the language itself.
What you're asking totally depends on the libraries or framework you'll decide to use to connect to databases. There is no standard library that have this purpose. So first choose the database, then the library to connect to it, then you'll get the configuration infos in the library documentation.
There's nothing in the standard, but Boost.Program_options is a good library for retrieving/storing configuration.
Obviously the configuration file must be stored in the correct location: if it's a per-user configuration file, on Windows it will be stored in the %APPDATA%1 directory (usually in a subdirectory named after your application), on Linux in a dot file under the home directory. For non-user specific configuration files, they may be stored in the "All Users" Application Data folder on Windows1, and under /etc on Linux2.
Naturally, you won't hardcode these paths, but you'll use SHGetFolderPath with the appropriate CSIDL values (or SHGetKnownFolderPath if you don't care about pre-Vista compatibility), like CSIDL_APPDATA for per-user settings, CSIDL_COMMON_APPDATA for settings common to all users.
Notice that /etc on Linux is writeable only by the superuser; I don't remember if the "all users" profile is writable for normal users under Windows.

Program configuration data in Unix/Linux

What is recommended way to keep a user configuration data in Unix/Linux?
My programming language is C++. Configuration data will be kept in XML/text/binary format, I have no problem with handling such files. I want to know where can I keep them. For example, in the Windows OS configuration data may be kept in the Registry (old way) or in user application data directory. What about Linux?
I need read/write access to configuration files.
The concept of the registry is peculiar to Windows, and Microsoft once admitted to it being ill-conceived (see this, this, this, this (see #2), and this).
In Unix and Linux, configuration for system-wide programs is in /etc or maybe an application-specific subdirectory.
Per user configuration data are kept in the user's home directory in a hidden file—in text format—or an application-specific hidden directory in the user's home directory. The proper way to reference the home directory is through the environment variable HOME. Hidden files and directories are created by making . the first character of the name.
Examples for system-wide configuration is /etc/wgetrc and /etc/ssh/. Examples of per-user data are $HOME/.bashrc and $HOME/.mozilla/.
The XDG Base Directory Specification specifies where configuration and other files should be stored in Linux and other X-based operating systems:
http://freedesktop.org/wiki/Specifications/basedir-spec
This is the modern way, and may eventually reduce the dotfile mess in the typical user's home directory.
Dotfiles are the classic Unix solution. If you want to deal with reading/writing everything yourself, go for it.
However, most modern programs I use have used GConf for storing preferences. It makes a lot of things easier, both as a developer and as a user (and apparently as an administrator, but I have no experience there).
That depends a little on your flavor of Linux but as a general rule most programs have the system default configuration somewhere in /etc with .config files in your home directory that can override the defaults in the /etc dir.
Great point .config should be .[Name of config file]