123

My CMakeLists.txt contains this line:

file(GLOB lib_srcs Half/half.cpp Iex/*.cpp IlmThread/*.cpp Imath/*.cpp IlmImf/*.cpp)

and the IlmImf folder contains b44ExpLogTable.cpp, which I need to exclude from the build.

How to achieve that?

user7610
  • 25,267
  • 15
  • 124
  • 150
berak
  • 39,159
  • 9
  • 91
  • 89

4 Answers4

133

You can use the list function to manipulate the list, for example:

list(REMOVE_ITEM <list> <value> [<value> ...])

In your case, maybe something like this will work:

list(REMOVE_ITEM lib_srcs "IlmImf/b44ExpLogTable.cpp")
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Lindydancer
  • 25,428
  • 4
  • 49
  • 68
  • 1
    besides lib_srcs instead of lib_src and IlmImf instead of IlmThread , That did the trick ! thanks a ton ! – berak Mar 21 '13 at 15:31
  • 25
    Note: When removing the item of the list, make sure the value you are searching for matches exactly as it is in the list. I was having some troubles mixing ${CMAKE_SOURCE_DIR}/src/file_to_remove.cpp with ${CMAKE_CURRENT_SOURCE_DIR}/../file_to_remove.cpp. It points to the same location, but it's not the same string. message("${VARIABLE_NAME}") can help you debug those contents. – hbobenicio Oct 10 '16 at 17:01
  • 1
    This doesn't help if your using `CONFIGURE_DEPENDS` and need to exclude a file produced by the build. A filter on the list after the `file` call still triggers a rebuild which, in my case, I am trying to avoid. – simon.watts Feb 21 '19 at 16:00
  • 1
    It's much better to use `list(FILTER` – hukeping Sep 02 '19 at 04:00
  • 7
    The above solution does not work for me with camke version 3.10.2 But the solution below: `list(FILTER REGEX )` works well for me. – MH Yip Oct 16 '19 at 12:27
  • @MHYip, It should work, but only if you spell the item to be removed exactly as it is in the list. However, the REGEX solution gives you more flexibility, so if it works for you, that's great. – Lindydancer Oct 17 '19 at 14:10
79

FILTER is another option which could be more convenient in some cases:

list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>)

This line excludes every item ending with the required filename:

list(FILTER lib_srcs EXCLUDE REGEX ".*b44ExpLogTable\\.cpp$")

Here is Regex Specification for cmake:

The following characters have special meaning in regular expressions:

^         Matches at the beginning of input
$         Matches at the end of input
.         Matches any single character
[ ]       Matches any character(s) inside the brackets
[^ ]      Matches any character(s) not inside the brackets
 -        Inside brackets, specifies an inclusive range between
          characters on either side e.g. [a-f] is [abcdef]
          To match a literal - using brackets, make it the first
          or the last character e.g. [+*/-] matches basic
          mathematical operators.
*         Matches preceding pattern zero or more times
+         Matches preceding pattern one or more times
?         Matches preceding pattern zero or once only
|         Matches a pattern on either side of the |
()        Saves a matched subexpression, which can be referenced
          in the REGEX REPLACE operation. Additionally it is saved
          by all regular expression-related commands, including
          e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).
Community
  • 1
  • 1
Eugene
  • 3,335
  • 3
  • 36
  • 44
  • 2
    Can be much more reliable than mucking around with absolute/relative pathes – EFraim May 30 '18 at 09:09
  • 2
    Much better than `list(REMOVE_ITEM` – ceztko Jun 01 '18 at 22:14
  • 2
    Note that `list(FILTER ...)` was introduced in cmake v3.6: https://stackoverflow.com/a/42167646/3476780 – yano Jun 06 '18 at 00:01
  • This is definitely a better answer, although if you're trying to use this to exclude a whole directory or if your regex is messed up, you might exclude more than you want. For example, trying to exclude `.*test/.*` might exclude everything if your project is inside a directory tree where one of the parent directories is called something like `mytest`. – adentinger Jul 08 '19 at 12:27
  • 1
    You forgot to escape the dot between file name stem and extension. Thus, it will match to any character between stem and extension, e.g. `b44ExpLogTableacpp` – Mustafa Kemal GILOR Apr 10 '21 at 13:40
  • 1
    The corrected expression should be: `list(FILTER lib_srcs EXCLUDE REGEX ".*b44ExpLogTable\\.cpp$")` – Mustafa Kemal GILOR Apr 10 '21 at 13:45
4

try this : CMakeLists.txt

install(DIRECTORY   ${CMAKE_SOURCE_DIR}/ 
            DESTINATION ${CMAKE_INSTALL_PREFIX}
            COMPONENT   copy-files
            PATTERN     ".git*"   EXCLUDE
            PATTERN     "*.in"    EXCLUDE
            PATTERN     "*/build" EXCLUDE)

add_custom_target(copy-files
            COMMAND ${CMAKE_COMMAND} -D COMPONENT=copy-files
            -P cmake_install.cmake)
$cmake <src_path> -DCMAKE_INSTALL_PREFIX=<install_path>
$cmake --build . --target copy-files
James
  • 111
  • 9
  • It doesn't answer the OP's question as question was rather specific. But I found this answer to be the most suitable nevertheless. If the real issue is what NOT to include in **installation** builds, this is an elegant solution. Especially if one has a more than one special build-targets (add_custom_target) into a common build-directory, this is easier to maintain. Note: COMPONENT is not needed for "cover all" cases. Works excellent with CPack (tested with DEB generator, cmake version 3.18.4) – Michael Ambrus Jul 19 '22 at 11:59
0

I have an alternative solution worth noticing: mark source as header file. This way it will not be part of the build process, but will be visible in IDE (verified on Visual Studio and Xcode):

set_source_files_properties(b44ExpLogTable.cpp,
                            PROPERTIES HEADER_FILE_ONLY TRUE)

I use this when some source file is platform specific. It is great since if some symbol has to be modified in many places and working on one platform then other platform specific source will can be visible and can be updated too.

For that I've created a helper function which works great in my current project.

I didn't use this method with file GLOB yet.

Marek R
  • 32,568
  • 6
  • 55
  • 140