[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