Steven Wilson wrote:
Consider the following simple C++ file foo.cpp:

#include <iostream>

int main()
{
    std::cout << "bar" << std::endl;
    return 0;
}


Now consider the following CMakeLists.txt file for foo.cpp:


cmake_minimum_required(VERSION 2.6)

project(Bug)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)


add_executable(foo foo.cpp)

get_target_property(FOO_LOCATION foo LOCATION)

message("${FOO_LOCATION}")

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/bar
    COMMAND ${CMAKE_COMMAND} -E make_directory bat
    COMMAND chdir bat
    COMMAND ${FOO_LOCATION} > ${CMAKE_CURRENT_BINARY_DIR}/bar
    DEPENDS foo
)


add_custom_target(Bar DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bar)


When you configure this project using the Windows Visual Studio 9 generator, the generation step correctly displays(ie from the message() command) the value C:\path\to\build\directory\bin\$(OutDir)\foo.exe for the variable FOO_LOCATION. The problem comes in the add_custom_command step. The generator writes the following line into the .vcproj file:

bin\$(OutDir)\foo.exe > C:\path\to\build\directory\bar

What I'm pointing out is that the generator puts a path to foo.exe that is not the full path name and this behavior causes the add_custom_command build step to fail because the custom command includes a chdir command so the current working directory has changed and bin\$(OutDir)\foo.exe is not longer available.

Now, if you instead modify the add_custom_command the line to read:

COMMAND "..\${FOO_LOCATION}|" > ${CMAKE_CURRENT_BINARY_DIR}/bar

the generator instead puts the following in the project files:

..\C:\path\to\build\directory\bin\$(OutDir)\foo.exe

?!?

The correct path now appears, but it is wrong because of the ..\ prepended to the value.

What is going on? Why doesn't the value of FOO_LOCATION always and everywhere stay C:\path\to\build\directory\bin\$(OutDir)\foo.exe?

It's converted to a path relative to the expected working directory
of the custom command.  This is the current binary directory by
default, or can be set with the add_custom_command() call through the
WORKING_DIRECTORY option.  You can use file(MAKE_DIRECTORY) to prepare
the directory at CMake time, or a separate custom command to make it.

FYI, the LOCATION property is not necessary in CMake 2.6.  You can
just name the target:

  file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bat)
  add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/bar
    COMMAND foo > ${CMAKE_CURRENT_BINARY_DIR}/bar
    DEPENDS foo
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bat
    )

-Brad
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to