[CMake] Paths for targets to COMMAND in ADD_CUSTOM_COMMAND

Alexander Neundorf a.neundorf-work at gmx.net
Thu Mar 27 19:40:04 EDT 2008


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.

Alex


More information about the CMake mailing list