How to get an Application Data/Log folder not specific to OS in C++

Viewed 98
  • My C++ program produce some logs and data (text/3D files/etc),
  • My program should not be specific to an OS (Posix and Windows),
  • The data can be lost on program/machine restart (when the program starts, it cleans this folder anyway).

I found many thread on where to place the application data and how to get this folder from code, but they are all platform specific.
Some examples:
Linux: /var/log/your_app /home/user/.your_app/logs /var/lib/your_app
Windows: %ProgramData%\your_app %LOCALAPPDATA%\your_app

At first, I wanted to store this data in the program folder (where the executable is stored) using relative path, but the program does not have write privileges in his own folder.

The only not OS specified solution that I've found is to use std::filesystem::temp_directory_path.
However this folder look like a mess (at least on Windows) with dozens of temp files/folders generated by other process.
I'm not sure it's the best thing to send a user in this jungle.
enter image description here

Question

  • Is it a good solution to use the TEMP folder to store Application Data/Logs ?
  • If not, how would you do in C++ to get the best directory where to store Data/Logs for an application, regardless of the OS ?
1 Answers

According to ThomasMatthews comment there is no standard directory to store App Data or logs. So there is no generic function or environment variable to retrieve this directory.
You need a pre-compilation code that set the best directory for each OS.

C++ example using preprocessor directives:

#define PROJECT_NAME "your_app"

#include <iostream>
#include <stdlib.h>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{
#ifdef WIN32
  fs::path def_appdata = fs::path(std::getenv("LOCALAPPDATA"))/ PROJECT_NAME;
#elif UNIX
  fs::path def_appdata = fs::path(std::getenv("HOME")) / PROJECT_NAME;
#endif 

  std::cout << def_appdata << std::endl;
}

And if you use CMake, you can do this to set a #define with the correct directory:

if(UNIX)
    file(TO_CMAKE_PATH "$ENV{HOME}/${PROJECT_NAME}" DEF_APPDATA)
elseif(WIN32)
    file(TO_CMAKE_PATH "$ENV{LOCALAPPDATA}\\${PROJECT_NAME}" DEF_APPDATA)
else()
    message(SEND_ERROR "OS not recognized !")
    file(TO_CMAKE_PATH "./data" DEF_APPDATA)
endif()
target_compile_definitions(${TARGET_NAME} PRIVATE DEF_APPDATA="${DEF_APPDATA}")

Here the application data will be saved in:
Linux: $HOME/your_app
Windows: %LOCALAPPDATA%\your_app

Related