[CMake] Paths for targets to COMMAND in ADD_CUSTOM_COMMAND

Jonas Karlsson jonka750 at student.liu.se
Fri Mar 28 16:38:56 EDT 2008


On Fri, 28 Mar 2008 00:40:04 +0100, Alexander Neundorf <a.neundorf-work at gmx.net> wrote:

> On Thursday 27 March 2008, Jonas Karlsson wrote:
>> On 25/03/2008, Jonas Karlsson <cj.karlsson at gmail.com> wrote:
>> > Hello,
>>
>> First of all I must say I'm sorry that the message got sent twice.
>>
>> >  I'm trying to build GTK-Qt-Engine 1.1, which use CMake as build system,
>> >  but it fails almost halfway through with the following message:
>> >  [ 44%] Generating ../../po/bg.gmo
>> >  /System/Links/Executables/msgfmt: error while opening "bg.po" for
>> > reading: No such file or directory
>>
>> After some more experimenting I've come to the conclusion that this might
>> be a bug because the inconsistant behaviour between build and install and
>> if you create your build directory as a subdirectory to the source or as a
>> directory somewhere else.
>>
>> The following custom command and install macros are defined in a section
>> that loops over *.po files:
>>
>>         ADD_CUSTOM_COMMAND(
>>                 OUTPUT ${_out}
>>                 COMMAND ${MSGFMT_EXECUTABLE} -o ${_out} ${_file}
>>                 DEPENDS ${_file}
>>         )
>>
>>         INSTALL(
>>                 FILES ${_out}
>>                 DESTINATION share/locale/${_file_we}/LC_MESSAGES/
>>                 RENAME gtkqtengine.mo
>>         )
>>
>> These rules generate the following build and install rules if cmake is
>> called in a
>> build directory as subdirectory to the sources:
>>
>> ../po/bg.gmo: ../po/bg.po
>>         $(CMAKE_COMMAND) -E cmake_progress_report
>> /Files/Compile/Sources/gtk-qt-engine/_build/CMakeFiles
>> $(CMAKE_PROGRESS_1)
>>         @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue
>> --bold "Generating ../../po/bg.gmo"
>>         cd /Files/Compile/Sources/gtk-qt-engine/_build/po &&
>> /System/Links/Executables/msgfmt -o bg.gmo bg.po
>>
>> FILE(INSTALL DESTINATION
>> "${CMAKE_INSTALL_PREFIX}/share/locale/bg/LC_MESSAGES" TYPE FILE RENAME
>> "gtkqtengine.mo" COMPONENTS "Unspecified" FILES
>> "/Files/Compile/Sources/gtk-qt-engine/po/bg.gmo")
>>
>> Notice that the cmake_echo_color command have relative path, "cd" before
>> the custom command has the build directory as target and the custom command
>> has no path prefix to the argument files. This while the install target has
>> absolute path to the file. Four different references...
>> It doesn't matter if I call cmake with relative or full path to the
>> sources.
>>
>> If I instead make a direcotry at the same level as the source directory (or
>> anywhere else besides inside the source directory) the following custom
>> command rule is generated:
>>
>> ../gtk-qt-engine/po/bg.gmo: ../gtk-qt-engine/po/bg.po
>>         $(CMAKE_COMMAND) -E cmake_progress_report
>> /Files/Compile/Sources/gtk-qt-engine-build/CMakeFiles
>> $(CMAKE_PROGRESS_1)
>>         @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue
>> --bold "Generating ../../gtk-qt-engine/po/bg.gmo"
>>         cd /Files/Compile/Sources/gtk-qt-engine-build/po &&
>> /System/Links/Executables/msgfmt -o bg.gmo bg.po
>>
>> The difference here is that "cd" still has absolute path, but it changes to
>> the _source_ directory. The install rule is still the same.
>>
>> Ultimately, as a build directory is recommended I'd like the command to put
>> the files defined as OUTPUT in the build directory. If cmake use "cd" to go
>> to the source directory and have relative/full path to build directory for
>> the output file or
>> if cmake stays in the build directory and reference the files defined as
>> DEPENDS with full/relative paths doesn't matter. I have also tried to use
>> "ARGS -o ${_out} ${_file}" to change the behaviour, but there was no
>> difference.
>>
>> I know people have recommended having build directory as subdirectory to
>> the source due to integration with the IDE works better, so shouldn't this
>> work?
>
> If unsure, always use ${CMAKE_CURRENT_BINARY_DIR}/filename.out as output
> filename, i.e. with the full path.
>
> You posted:
>
> FILE(GLOB _pofiles *.po)
>
> FOREACH(_file ${_pofiles})
>          GET_FILENAME_COMPONENT(_file_we ${_file} NAME_WE)
>          SET(_out "${_file_we}.gmo")
>          SET(_in "${_file_we}.po")
>
>          ADD_CUSTOM_COMMAND(
>                  OUTPUT ${_out}
>                  COMMAND ${MSGFMT_EXECUTABLE} -o ${_out} ${_in}
>                  DEPENDS ${_in}
>          )
>
>          INSTALL(
>                  FILES ${_out}
>                  DESTINATION share/locale/${_file_we}/LC_MESSAGES/
>                  RENAME gtkqtengine.mo
>          )
>
>          SET(_outputs ${_outputs} ${_out})
> ENDFOREACH(_file)
>
> _pofiles will have the full path. After get_filename_component(NAME_WE) you
> only have the filename left without path and extension.
> So do something like this:
>
>          SET(_out "${CMAKE_CURRENT_BINARY_DIR}/${_file_we}.gmo")
>
> and just use _file instead of _in, this has the full path and should work.
>
Yes, that works, thanks.

However, I still think this can be concidered a bug, since there is too much
inconsistency. First of all, if I pass the full path to the input and output
files (or if that should matter), why does cmake introduce "cd" before the
command? A "cd" that had the wrong path if the build directory was a
subdirecory to the source (I think the bug is here). And even though
relative, cmake_echo_color always had the correct path in both cases. And I
still think there should be a way to make cmake separate source and result
files for custom commands, just like the build does.

-- 
/Jonas

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


More information about the CMake mailing list