Passing escaped strings from macros to functions


The following project:

cmake_minimum_required(VERSION 3.15)


    message("func  ARGV: ${ARGV}")

    message("macro ARGV: ${ARGV}")

my_func (LIBS_SUFFIX="\\\\"_${CMAKE_SYSTEM_PROCESSOR}.so\\\\"")

generates the following output:

func  ARGV: LIBS_SUFFIX="\\"\\""
macro ARGV: LIBS_SUFFIX="\"\""

In the macro case. a pair of slashes disappear.

My ultimate goal is to allow passing a value like LIBS_SUFFIX="\\\\"_${CMAKE_SYSTEM_PROCESSOR}.so\\\\"" to a macro, and within that macro to forward the exact same value to a function.

So something like:

# do stuff

Is this somehow achievable? Am supposed to do something like? What else would i be missing then?
string(REPLACE "\\" "\\\\" my_var ${ARGV})

The reasoning is to provide a compatibility api for a function that got renamed, and thus the arguments from the macro should be sent verbatim to the function.


Macros are weird. They act akin to C’s preprocessor. First, the argument variables are expanded within the body of the macro definition and then it is executed. This is why you lose a level of escaping through it. Do you need it to be a macro? set(PARENT_SCOPE) can help avoid using it if it is sufficient. I don’t know of a way to avoid the escaping problem because the argument is only available via the initial expansion (if (DEFINED argname) is false in a macro unless it leaks from the calling scope).

Relevant issues:

The string(REPLACE) approach to re-escape backslashes within macros before forwarding them on should be fine.

Ok, thanks for the answers!

set(var PARENT_SCOPE) + function only works if you know the whole set of variables that you need to propagate from within the function to the outside function.

After some consideration, I believe function wrapping instead of macro wrapping will work fine for me.

But it’s good to know that it’s a semi-issue.