[CMake] add_custom_command/get_target_property bug on Windows?
Brad King
brad.king at kitware.com
Thu Oct 22 08:22:07 EDT 2009
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
More information about the CMake
mailing list