11

I found "[" and "]" might have special meanings in a semicolon-separated list in CMake. When I try this code in CMakeLists.txt:

set(XX "a" "b" "[" "]")
message("${XX}")

foreach(x ${XX})
        message("--> ${x}")
endforeach()

I expect the result:

a;b;[;]
--> a
--> b
--> [
--> ]

However I got this:

a;b;[;]
--> a
--> b
--> [;]

I didn't find any documentation for the usage of "[" and "]". Is it possible to escape these characters so that I can get the expected result? I am using CMake 2.8.12.2. Thanks for any help :)

Cheng Li
  • 111
  • 4
  • 5
    I've found this [bug](http://public.kitware.com/Bug/view.php?id=9317). –  Sep 26 '14 at 11:22
  • 1
    Thank you :) Maybe I need to replace brackets with other strings and then replace them back to workaround this bug. – Cheng Li Sep 26 '14 at 11:36
  • I need to extract strings from some config files from 3rd-party libraries and then generate an xml file for my android project. unfortunately the config files contain brackets and make CMake confused. – Cheng Li Oct 12 '14 at 14:47

2 Answers2

2

According to the documentation opening square bracket definitely has a special meaning:

Note: CMake versions prior to 3.0 do not support bracket arguments. They interpret the opening bracket as the start of an Unquoted Argument.

So the problem is mixing Quoted and Unquoted arguments. Possible workaround in your case is to replace opening square bracket to something else in initialization and later replace it back, like this:

CMAKE_MINIMUM_REQUIRED (VERSION 2.8.11)
PROJECT (HELLO NONE)

SET(XX a b BRACKET ])

MESSAGE("${XX}")

FOREACH(x ${XX})
    STRING(REGEX REPLACE "BRACKET" "[" x ${x})
    MESSAGE("--> ${x}")
ENDFOREACH()
Andrew Selivanov
  • 1,306
  • 15
  • 22
  • 1
    The handling of closing bracket is also weird. For example, if you try `set(XX "a" "b" "]" "c" "d")`, you will get `--> ];c;d` instead of 3 separated items. I end up with the workround by replacing all brackets with something else and then replace them back. It is dirty but works for me. :) – Cheng Li Oct 12 '14 at 14:40
  • Bracketed arguments require double brackets, `[[...]]`, or with a matching sequence of `=` between them; `[===[...]===]`. Single brackets shouldn't be interpreted as a bracketed argument (or bracketed comment). – simon.watts Jul 06 '22 at 10:18
1

As noted in another answer, the square brackets are now used to delimit "long form" arguments or long form comments, as well documented in CMake 3.0 and later.

A single pair of square brackets with ; inside have also long been used to designate registry [key;value] pairs on Windows. An example of this behavior is shown in the CMake file InstallRequiredSystemLibraries.cmake :

get_filename_component(msvc_install_dir
  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE)

The way it's implemented has the unfortunate side effect of causing confusion when somebody wants to have list values containing square brackets, hence this question on SO.

DLRdave
  • 13,876
  • 4
  • 53
  • 70