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