[CMake] Does the echo command use the system shell?

Michael Wild themiwi at gmail.com
Thu Jul 29 00:21:58 EDT 2010


On 29. Jul, 2010, at 4:19 , Óscar Fuentes wrote:

> Eric Noulard <eric.noulard at gmail.com>
> writes:
> 
>> I think you are wrong.
>> 
>> May be you can try the attach script.
>> 
>> try:
>> cmake -DYOURSTRING="I like # \ it" -DTHE_FILE=toto.txt -P writeany.cmake
>> 
>> You shouldn't have "quite" problem with the previous approach.
> 
> I tried this on Linux:
> 
> add_custom_command(OUTPUT ${EMACS_BUILD_DIR}/src/buildobj.h
>  COMMAND cmake -DYOURSTRING="#define BUILDOBJ" -DTHE_FILE=buildobj.h -P writeany.cmake
>  COMMENT "Creating buildobj.h"
>  )
> 
> It didn't create the file. So tried this:
> 
> add_custom_command(OUTPUT ${EMACS_BUILD_DIR}/src/buildobj.h
>  COMMAND cmake -DYOURSTRING="\#define BUILDOBJ" -DTHE_FILE=buildobj.h -P writeany.cmake
>  COMMENT "Creating buildobj.h"
>  )
> 
> It put this text on the resulting file:
> 
> #define\ BUILDOBJ
> 
> That's not quite what I wanted.
> 
> I would say that having to write and invoke a script for this trivial
> task seems way too much trouble imposed by an otherwise absolute
> time-saver as cmake is.
> 
>>> The task here is to write a literal string containing a "special"
>>> character (#) to a file, at build time. For "cmake -E echo" it requires
>>> platform-dependent escape sequences. My idea about the cmake -E commands
>>> was that they purpose is to abstract platform differences, but seems
>>> that that is not entirely correct, as they inherit some traits from the
>>> underlying platform. Or is it a bug?
>> 
>> I would say a feature :-)
>> 
>> You do not want to have to "escape" some sequences
> 
> I'm happy escaping whatever as much sequences as necessary. What is not
> okay is to change escape rules depending on the plataform (or worse,
> depending on the shell cmake uses for the generator. "Mingw Makefiles"
> -> cmd.exe, "MSYS Makefiles" -> sh.exe)
> 
> [snip]
> 
>> More seriously I think it's complicated to avoid system specific
>> issues with a command like "echo".
> 
> It should be possible to pass an arbitrary string (containing
> backslashes if necessary) to "echo" and send it to the console or
> redirected to a file on a platform independent way. That means avoiding
> any middleman that may reinterpret certain characters as per its own
> rules. If you pass the string through the shell, all hopes of platform
> independence are gone.
> 
>> I think that if you tell me what you would expect I may probably gives
>> you an example of mine were YOUR bug is a feature for ME.
> 
> I doubt that, because on the end we want the same: saying "take this
> string and put it on that file." We can then open the file and test
> that, effectively, the string is there.
> 
> OTOH I can't think of a real application for this sort of behavior of
> the "echo" command. That is, nothing that you could achieve invoking the
> platform's shell.
> 
>> That said, that's my own opinion, I may be wrong.

How much of that file has to be "dynamic"? E.g. if you know the full contents, up to some file name, you can use configure_file to create writeany.cmake to look like this:

file(WRITE "${THEFILE}" "#define ${THEDEFINE}")

and then invoke it with

add_custom_command(OUTPUT ${EMACS_BUILD_DIR}/src/buildobj.h
 COMMAND cmake -DTHEDEFINE="BUILDOBJ" -DTHE_FILE="${EMACS_BUILD_DIR}/src/buildobj.h" -P writeany.cmake
 COMMENT "Creating buildobj.h"
 )

And if the general structure of buildobj.h is also know statically, you can use a buildobj.h.in template file and replace the file(WRITE ...) stuff with a configure_file in the writeany.cmake.

Perhaps you need to tell us what it is that you are trying to achieve, because I suspect that you are over-thinking things and that there is a much simpler solution. E.g. what should buildobj.h contain (semantically, not the exact strings), and why is it only known at build time? 

HTH

Michael


More information about the CMake mailing list