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.