我们正在使用CMake来编译我们的软件库。问题是,团队中有几个新人被接受,他们在文件/文件夹名称中使用变音符号。
CMake Generators通常会错误地读取诸如á,ř,š,ě,ž
之类的字符,随后构建会因一些晦涩的行为而失败(创建名称混乱的新文件夹等)。
CMAKE_CURRENT_LIST_DIR
的价值特别感兴趣。答案 0 :(得分:0)
A-Z, a-z, 0-9, '\', '/', '-', '_', ':' and ' ' (space)
。此特定解决方案的分步说明可能是:
[i..length-of-string - 1]
并从_name
的那个位置获取相应的字符A-Z
或a-z
匹配,如果找到,请转到下一个字符0-9
匹配,如果找到,请转到下一个字符#
# validate_name(<name>)
# Checks if the specified string consists of legal ASCII characters.
# If an illegal character is found, then a build error is produced.
# Legal characters are: A-Z, a-z, 0-9 and '\', '/', '-', '_', ':' and ' '.
#
# _name: The string to examine
#
# Example: validate_name("C:\\foo\\bar")
# validate_name("/home/user/code/project")
#
function(validate_name _name)
# For simplicity, set all valid special characters here.
set(valid_specials "\\\\/-_: ")
string(LENGTH "${_name}" name_length)
math(EXPR name_length "${name_length}-1")
foreach(i RANGE 0 ${name_length})
# Get next character.
string(SUBSTRING "${_name}" ${i} 1 current_char)
# Convert said character to lowercase. This way we don't have to consider
# A-Z explicitly.
string(TOLOWER ${current_char} current_char)
# Is it A-Z or a-z?
if (NOT (("${current_char}" STRLESS "a") OR ("${current_char}" STRGREATER "z")))
# It's A-Z or a-z.
continue()
endif()
# Is it a number?
if (NOT (("${current_char}" STRLESS "0") OR ("${current_char}" STRGREATER "9")))
# It's a number.
continue()
endif()
# Is it a valid "special" character?
string(FIND "${valid_specials}" "${current_char}" valid_special_found)
if (valid_special_found GREATER -1)
continue()
endif()
message(FATAL_ERROR "'${current_char}' is not a legal character in this context.")
endforeach()
endfunction()
如果要减小代码的大小,可以将所有允许的字符放在单个字符串中并使用string(FIND ...)
,就像对特殊字符所做的操作一样。无论如何,性能并不重要。我这样做是为了让您知道STRLESS
等。
最后,对于您的情况,您可以使用validate_name(${CMAKE_CURRENT_LIST_DIR})
另一种可能的解决方案是仅使用正则表达式:
set(NAME "home/user/path")
string(REGEX MATCH "[A-Za-z0-9 \\\\/:_-]*" MATCH "${NAME}")
if (NOT "${MATCH}" STREQUAL "${NAME}")
message(FATAL_ERROR "Illegal character(s) found.")
endif()
如果找到该规则未定义的任何字符,这将产生一个不同的字符串。如果字符串有效,则MATCH == NAME
。请注意,如果第一个字符不合法,CMake
将抛出自己的错误。我远不是正则表达式专家,所以我敢肯定有一个更优雅的解决方案。
无论如何,我认为这至少应该让您入门。让我知道是否需要进一步说明。