Search code examples
cmakecmake-languagecmakelists-options

Can I control sources exclusion from target_sources in CMake?


I am new in CMake and I was wondering whether there is a possibility to exclude certain sources from target_sources() based on a variable.

Let's say I have this below

target_sources(myTarget
    PUBLIC
    PRIVATE
        myDir1/src/a.c
        myDir2/src/b.c
        myDir3/src/c.c      
    INTERFACE
)

target_include_directories(myTarget
    PUBLIC
    PRIVATE       
        myDir1/inc
        myDir2/inc
        myDir3/inc  
    INTERFACE
)

I would like to exclude/include sources/directories from myDir3 based on a flag called i.e. myFlag. How can I achieve this?

target_sources(myTarget
    PUBLIC
    PRIVATE
        myDir1/src/a.c
        myDir2/src/b.c
        if(DEFINED myFlag)
           myDir3/src/c.c
        endif()
    INTERFACE
)

target_include_directories(myTarget
    PUBLIC
    PRIVATE        
        myDir1/inc
        myDir2/inc
        if(DEFINED myFlag)
           myDir3/inc  
        endif()
    INTERFACE
)

Solution

  • You cannot put if statements inside a command's argument list. The target_* commands don't overwrite, but append, so the easiest solution is the following:

    target_sources(
      myTarget
      PRIVATE
        myDir1/src/a.c
        myDir2/src/b.c 
    )
    if (myFlag) 
      target_sources(myTarget PRIVATE myDir3/src/c.c)
    endif ()
    
    target_include_directories(
      myTarget
      PRIVATE
        myDir1/inc
        myDir2/inc
    )
    if (myFlag) 
      target_include_directories(myTarget PRIVATE myDir3/inc)
    endif ()
    

    Another more declarative option would be to use a generator expression, like so:

    target_sources(
      myTarget
      PRIVATE
        myDir1/src/a.c
        myDir2/src/b.c
        $<$<BOOL:${myFlag}>:myDir3/src/c.c>
    )