Issue
I'm new in Cmake. And I try to use Cmake to construct my project.
In my project, I need to load some resources in runtime. for instance:
string inFileName = "../Resources/resource.txt";
// string inFileName = "../../Resources/resource.txt";
ifstream ifs;
ifs.open(inFileName.c_str());
if (ifs) {
....
}
But when I use the command line cmake ../
and cmake --build . --config Release
in project/build. my file path should be relative to ${PROJEDCT_BINARY}
, i.e. inFileName = "../resources/resource.txt"
.
But when I use cmake ../
and open the sln file with VS2019 then right-click to build and run, my file path should be relative to the executable, i.e. inFileName = "../../resources/resource.txt"
.
I don't know why this happened, and I search through Internet, It seems no one else encounters this stupid question...
Below is my file structure.
|--3rdParty
|----CmakeLists.txt
|--include
|----header.h
|--source
|----source.cpp
|----CmakeLists.txt
|--resources
|----resource.txt
|--CmakeLists
and my root CmakeLists.txt
cmake_minimum_required(VERSION 3.12)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(OBMI VERSION 0.1.0.0 LANGUAGES C CXX CUDA)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
add_subdirectory(3rdParty)
add_subdirectory(source)
source/CmakeLists.txt
add_executable(mSI)
target_sources(mSI PRIVATE
${PROJECT_SOURCE_DIR}/include/header.h
# source
source.cpp
)
target_include_directories(multiSpectrumImaging
PRIVATE
${PROJECT_SOURCE_DIR})
target_link_libraries(mSI
PRIVATE
...
)
Solution
When using relative paths to load files, the resolution of the final filename depends on the current working directory. The relative path is appended to that working directory. That current working directory is not necessarily the same as the path of your application; it will be the path of the surrounding environment from which the application is started (or can be set specifically for a debug environment in most IDE's).
You don't specify exactly how you run your program when you run it not from the IDE - just by double-clicking the executable maybe? You also don't tell us where the executable is built in relation to your sources?
Specifically for running from Visual Studio, you can set the working directory in the "Debugging" section of the Project Properties.
For a more flexible solution, what I typically do is to determine the path of your executable, and then appending the relative path to load resources to that.
Basically, the full executable path is stored in argv[0]
(if you have a int main(int argc, char** argv) {...}
, i.e., the first element of the second argument to your main function). For more information on this, see for example the answers to this other question.
Answered By - codeling Answer Checked By - Willingham (WPSolving Volunteer)