41

I have a project with the following structure:

project_name/CMakeLists.txt
project_name/src
project_name/resources
...
project_name-build/configuration_name/project_name.exe

I want my application to be run in the root project directory project_name so it can directly access resources.

Does CMake provide a method to specify this property, or will I have to manually set it in each build environment I use?

I've looked around in the documentation and haven't found anything other than the possibility of setting up a post-build event to run my project from the desired directory which is less than desirable. I also found that the working directory setting for Visual Studio is saved in a per-user file (.vcxproj.user) which I don't believe CMake generates (which points to the answer being probably no).

Peter Clark
  • 2,863
  • 3
  • 23
  • 37
  • 3
    CMake does not generate .user files but it gives you the ability to build your own CMake script to do so yourself using CMake commands to write the file and manipulate strings. – drescherjm May 30 '14 at 16:26

3 Answers3

61

Since CMake 3.8, there is the VS_DEBUGGER_WORKING_DIRECTORY target property, which allows you to set the debugger working directory for a target in Visual Studio.

Usage example:

set_property(TARGET MyTarget PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
starball
  • 20,030
  • 7
  • 43
  • 238
tambre
  • 4,625
  • 4
  • 42
  • 55
  • 2
    Good find ! Not sure why CMake chose to make the property VS specific : it could apply to other IDEs. – diapir Dec 03 '16 at 08:22
  • 1
    @diapir I submitted [issue #16478](https://gitlab.kitware.com/cmake/cmake/issues/16478) to track the problem you brought up. – tambre Dec 03 '16 at 10:23
  • Thanks for the raised issue. I think I got their logic : QtCreator, KDevelop, etc probably use separate project files while VS hard-codes the debugger working directory inside the .vcxproj file as `LocalDebuggerWorkingDirectory` ... which gets overwritten with each regeneration. I'll take a stroll over there. – diapir Dec 03 '16 at 13:48
  • 2
    I still think that this might make sense to not be so specific, so it can be also used by future generators for other IDEs and such. – tambre Dec 04 '16 at 19:19
  • What can I replace with 'MyTarget' so CMake set working directory for all of my targets? – 123iamking Sep 17 '17 at 05:35
  • 1
    @123iamking `VS_DEBUGGER_WORKING_DIRECTORY` is a per-target property and you can't set it on directories. It makes sense for a target (executable) to have only one working directory. If your working directory differed from source file to another, it would be a nightmare to debug and would likely cause compatibility problems, as it isn't supported natively by Windows - Windows only has a concept of a single working directory. You could use a macro, but I personally would prefer to have such modifications of target properties explicitly visible. – tambre Sep 17 '17 at 07:06
  • Don't worry, Visual Studio has the $(OutDir), so each executable has its own folder. set_target_properties(??? PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$(OutDir)") --> if I can replace the ???, it would be really cool :) ( you can use [if (MSVC)] to do this for VS only) - at least can I loop for the targets? – 123iamking Sep 17 '17 at 07:14
5

As drescherjm pointed out (in his comment on the question) CMake doesn't provide a method to directly set a working directory. However, CMake does provide indirect methods of doing so.

The path I think I'll take is to use the configure_file command to fill in a template .user file.

Community
  • 1
  • 1
Peter Clark
  • 2,863
  • 3
  • 23
  • 37
4

Here is an easier solution. Paste this at the end of your cmake:

file( WRITE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.vcxproj.user" 
    "<?xml version=\"1.0\" encoding=\"utf-8\"?>     \
    <Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">
    <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">
        <LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
        <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
    </PropertyGroup>
    <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">
        <LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
        <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
    </PropertyGroup>
    </Project>")

It overwrites the default vcxproj.user file for the current project and specifies $(OutDir) for the Working Directory as desired for debugging. Make sure that $PROJECT_NAME is your project name.

lithozine
  • 75
  • 1
  • 2