1

I'm making a game engine in C++ with CMake, I have the following directory structure:

Engine/
│  CMakeLists.txt
|
├─ lib/
|     libengine.a
|
├─ example/
│  │  CMakeLists.txt
|  |
│  ├─ bin/
|  |     example
|  |
│  └─ source/
│     └─ Example.cxx
|
├─ include/
│     Engine.hxx
|
└─ source/
      Engine.cxx

I've used this directory structure in a few other projects and it was ok until I encountered a problem, when I write to a file through the program it creates it in the 'Engine' directory, but I want it to create the file in 'Engine/example/bin/' (where the executable is) without any modifications to the C++ code. The same goes for reading files. At first I though this was because Engine::SaveGame() was in the engine library, so I tried to create a file through fstream in main but I got the same result.

Here are the cmake build scripts and the C++ source:

Engine/CMakeLists.txt:

cmake_minimum_required(VERSION 3.22)

project("Engine" LANGUAGES CXX)
message(STATUS "Running CMakeLists.txt for Engine")

option(LIB_BUILD_EXAMPLE "Build the example" ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-m64 -s -O3 -Wall -Wextra")

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY lib/)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY lib/)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY lib/)

add_library(engine STATIC
  source/Engine.cxx
)

target_include_directories(engine PUBLIC
  include/
)

if(LIB_BUILD_EXAMPLE)
  add_subdirectory(example)
endif()

Engine/include/Engine.hxx:

#pragma once

namespace Engine {
  extern void SaveGame();
} // namespace Engine

Engine/source/Engine.cxx:

#include "Engine.hxx"

#include <iostream>
#include <fstream>

namespace Engine {
  void SaveGame() {
    printf("Saving game...\n");

    std::ofstream output_file("game1.sav");
    output_file << "game data";
  }
} // namespace Engine

Engine/example/CMakeLists.txt:

cmake_minimum_required(VERSION 3.22)

project("Example" LANGUAGES CXX)
message(STATUS "Running CMakeLists.txt for Example")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-m64 -s -Wall -Wextra")

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY bin/)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin/)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY bin/)

add_executable(example
  source/Example.cxx
)

target_link_libraries(example
  engine
)

Engine/example/Example.cxx:

#include "Engine.hxx"
#include <fstream>

int main() {
  Engine::SaveGame();

  std::ofstream output_file("test.txt");
  output_file << "line 1\nline 2\n";
  return 0;
}

The way I build this project is by running cmake . and then make in the 'Engine' directory, and I run the example to test the engine by doing ./example/bin/example.

I think this has to do with some CMake option or something.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Marko
  • 11
  • 3
  • 1
    Your program creates a file using its relative path, so the file is created in the **current directory**, from which the program is run. So, if you run the program from the top-level directory, then it creates file in that directory. You could run the program from its directory (`example/bin/`), so it will create the file there. – Tsyvarev Aug 31 '22 at 23:32
  • Do want the executable in /example/bin for debugging purposes, or for creating a final "package". For the former, you should just set the current working directory to example/bin (probably using whatever IDE you are using). For the latter you should define install rules for the executable and install it by setting `CMAKE_INSTALL_PREFIX`. – local-ninja Sep 01 '22 at 00:24
  • If you want to get directory of running program at runtime, see these: [1](https://stackoverflow.com/q/1528298/11107541), [2](https://stackoverflow.com/q/143174/11107541), [3](https://stackoverflow.com/q/50889647/11107541). – starball Sep 01 '22 at 10:41
  • Does this answer your question? [Get path of executable](https://stackoverflow.com/questions/1528298/get-path-of-executable) – fabian Sep 01 '22 at 18:49
  • @Tsyvarev 's answer solved my problem. I had to run the program form it's current directory and not from the 'Engine' directory. – Marko Sep 06 '22 at 17:00

0 Answers0