如何在CMake生成的解决方案

时间:2016-04-24 02:20:25

标签: c++ path cmake resources

我正在使用CMake生成一个可执行文件和几个库。我已经将可执行文件的输出文件夹和所有库指定为一个共同的" bin"文件夹中。

使用:

set_target_properties (${PROJ} 
   PROPERTIES
   ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BIN_DIR}"
   ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BIN_DIR}"
   RUNTIME_OUTPUT_DIRECTORY_DEBUG "${BIN_DIR}"
   RUNTIME_OUTPUT_DIRECTORY_RELEASE "${BIN_DIR}"
   LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BIN_DIR}"
   LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BIN_DIR}"
)

在其中一个库中,我使用相对路径打开资源文件。这条路径是相对于" bin"文件夹.//Resources//file.jpg(因为Resources文件夹位于bin文件夹中)。

当我从visual studio调试器运行exe时,我看到它正确运行bin文件夹中的exe,但是当它尝试打开file.jpg时,它会查找相对于CMAKE_BINARY_DIR的路径。所以,CMAKE_BINARY_DIR/Resources/file.jpg。所以,我得到一个运行时错误,说找不到文件。

解决这个问题的最佳方法是什么?我不想复制CMAKE_BINARY_DIR中的所有资源。似乎应该有更好的方法。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

要解决您的问题,您需要在Visual Studio项目属性中设置正确的调试工作目录。它应该是$(TargetDir)而不是默认的$(ProjectDir)

Properties Dialog

为避免每次生成干净的解决方案时都必须手动修改设置,您可以使用CONFIGURE_FILE预生成默认的 .user 文件。

例如,我将以下模板用于我的VS 2013项目:

  • 在调试器中运行应用程序时使用的默认命令行参数
  • 要使用的工作目录(所有配置共享一个)
  • 调整PATH以包含具有所有预先构建的依赖关系和符号的目录

档案${ROOT}/build/template/executable_vs12.vcxproj.user

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
    <LocalDebuggerCommandArguments>-D20</LocalDebuggerCommandArguments>
    <LocalDebuggerWorkingDirectory>$(TargetDir)\..\..\common\</LocalDebuggerWorkingDirectory>
    <LocalDebuggerEnvironment>PATH=$(SolutionDir)..\deps\bin;$(Path)
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
</Project>

接下来,我有一个简单的 .cmake 文件,可以包含并包装配置步骤。

档案${ROOT}/build/debugger_config.cmake

IF(NOT COMMON_BUILD_DEBUGGER_CONFIG_INCLUDED)
SET(COMMON_BUILD_DEBUGGER_CONFIG_INCLUDED TRUE)
# =============================================================================
FUNCTION(CONFIGURE_DEBUGGER TARGET_NAME)
  CONFIGURE_FILE(${ROOT}/build/template/executable_vs12.vcxproj.user
    ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.vcxproj.user
    @ONLY
    )
ENDFUNCTION(CONFIGURE_DEBUGGER)
# =============================================================================
ENDIF(NOT COMMON_BUILD_DEBUGGER_CONFIG_INCLUDED)

最后,我在每个可执行目标定义之后调用此函数:

# This can go in top-level CMakeLists.txt
INCLUDE(${ROOT}/build/debugger_config.cmake)

# ...

ADD_EXECUTABLE(foo
  ${FOO_FILES}
)
CONFIGURE_DEBUGGER(foo)