list(REMOVE_ITEM)无法在cmake中运行

时间:2016-03-21 14:44:14

标签: cmake

以下是我的CMakeLists.txt文件的一部分。

file(GLOB SOURCES "xyz/*.cpp")
message("${SOURCES}")
list(REMOVE_ITEM SOURCES "src1.cpp")
message("${SOURCES}")

文件"xyz/*.cpp"中的文件是相对路径。 ${SOURCES}之前和之后REMOVE_ITEM的内容相同。

为什么list(REMOVE_ITEM)无效?任何帮助都是非常宝贵的。

2 个答案:

答案 0 :(得分:7)

我找到了解决问题的方法。我的解决方案背后的想法是,获取特殊cpp文件的完整路径,因为我看到,命令file(GLOB SOURCES "src/*.cpp")给了我一个完整路径列表。获取特殊文件的完整路径后,我可以从列表中删除。这是一个小例子

cmake_minimum_required(VERSION 3.4)
project(list_remove_item_ex)

file(GLOB SOURCES "src/*.cpp")
# this is the file I want to exclude / remove from the list
get_filename_component(full_path_test_cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/test.cpp ABSOLUTE)
message("${full_path_test_cpp}")

list(REMOVE_ITEM SOURCES "${full_path_test_cpp}")
message("${SOURCES}")

答案 1 :(得分:1)

In addition to accepted answer you can use the following function to filter lists using regexp:

# Filter values through regex
#   filter_regex({INCLUDE | EXCLUDE} <regex> <listname> [items...])
#   Element will included into result list if
#     INCLUDE is specified and it matches with regex or
#     EXCLUDE is specified and it doesn't match with regex.
# Example:
#   filter_regex(INCLUDE "(a|c)" LISTOUT a b c d) => a c
#   filter_regex(EXCLUDE "(a|c)" LISTOUT a b c d) => b d
function(filter_regex _action _regex _listname)
    # check an action
    if("${_action}" STREQUAL "INCLUDE")
        set(has_include TRUE)
    elseif("${_action}" STREQUAL "EXCLUDE")
        set(has_include FALSE)
    else()
        message(FATAL_ERROR "Incorrect value for ACTION: ${_action}")
    endif()

    set(${_listname})
    foreach(element ${ARGN})
        string(REGEX MATCH ${_regex} result ${element})
        if(result)
            if(has_include)
                list(APPEND ${_listname} ${element})
            endif()
        else()
            if(NOT has_include)
                list(APPEND ${_listname} ${element})
            endif()
        endif()
    endforeach()

    # put result in parent scope variable
    set(${_listname} ${${_listname}} PARENT_SCOPE)
endfunction()

For example in question it could look as the following:

file(GLOB SOURCES "xyz/*.cpp")
message("${SOURCES}")
filter_regex(EXCLUDE "src1\\.cpp" SOURCES ${SOURCES})
message("${SOURCES}")

(Because regexp is used then . is replaced with \\.)