Warning when JSON strings are stored in a cache variable

I need to manage some values coming from the strings JSON API in a cache variable. This triggers the following warning:

CMake Warning:
  Value of pb_json_arm contained a newline; truncating

How can I get rid of this warning?

To answer myself:

string(REGEX REPLACE "\n" "" _json "${_json}")

solved this. But there should be a switch…

The cache does not support newlines in the values. Never has. Such values have always needed to be properly handled. I don’t forsee the cache file format being updated to handle them either (it’s yet another short-signed encoding problem of CMake’s past; ;-separated lists being the main one).

Note that the blind replacement you are doing breaks the JSON if there are newlines not already represented by \n in any string content.

Note that the blind replacement you are doing breaks the JSON if there are newlines not already represented by \n in any string content.

You mean strings used inside the json elements? At least I can and do take care of those beforehand. So, what the ‘cache handler’ recognizes, are new lines after json elements (and these are created by string(JSON...)) - strings, lists, objects, etc. - I assume

Which leads to the question: What exactly is cmake itself 'truncating" here?

The value of any cache variable can only be stored in CMakeCache.txt faithfully up to the first newline, so it’s letting you know that the value will only be stored up to that point.

Perhaps instead of writing the actual JSON content into the cache, you may be better off writing it to a file and storing the name of that file in the cache. Don’t know if that fits your use case, but it would be more robust.

you may be better off writing it to a file

I would not prefer this. Not because of this particular use case (solved on my part). But:
The JSON string provides the first way in a long time to use a more complex data type than lists or lists of lists in cmake. I’m using it more and more, and don’t think it should add any more to cmake’s already vast trove of idiosyncrasies. Seamless interoperation with one of the most important ways to handle non-local information - cache variables - should be supported as much as possible, IMO.

Unfortunately, the cache format is not robust to extension as far as I know :frowning: . We do not error on unknown-types, so the “obvious” solution of “a cache variable of type JSON handles newlines differently” because the current behavior is “ignore that unknown type and treat it as STRING”, so older CMake versions which touch the cache will wreck it without any way to notice or guard against it.

so older CMake versions which touch the cache will wreck it without any way to notice or guard against it.

Maybe something like

set_json(cached_json my_json_string CACHE INTERNAL)

or

set(cached_json my_json_string CACHE INTERNAL JSON)

which will pass the argument to standard set if no cache is involved, and with prominent remark in his documentation what it will do (some kind of ‘tinifying’, ‘normalizing’, whatever) to the provided json in case it is, would be sufficient. In the cache case, a general limitation to INTERNAL (should cover most use cases) also might minimize impact to tooling like cmake-gui etc. .