3

I want to include some *.c and *.h files only for Windows OS. But I can't find the way how to do it without creating another target, what entails a mistake

I want to do something like this:

add_executable(${TARGET}
     main.cpp
     mainwindow.cpp
     mainwindow.h
     mainwindow.ui
if (WIN32)
     test.c
     test.h
endif()
)

Is there some way to do this?

drescherjm
  • 10,365
  • 5
  • 44
  • 64
AlexSmth
  • 43
  • 3
  • Use a variable and set – drescherjm May 05 '21 at 17:37
  • 1
    Does this answer your question? [OS specific instructions in CMAKE: How to?](https://stackoverflow.com/questions/9160335/os-specific-instructions-in-cmake-how-to) – gspr May 05 '21 at 17:42
  • BTW, I removed the `Qt` from the tags because I believe it is not important to the question or solution. It would be the same with or without using the `Qt` framework. – drescherjm May 05 '21 at 17:56

3 Answers3

5

The modern CMake solution is to use target_sources.

# common sources
add_executable(${TARGET}
     main.cpp
     mainwindow.cpp
     mainwindow.h
     mainwindow.ui
)

# Stuff only for WIN32
if (WIN32)
    target_sources(${TARGET}
        PRIVATE test.c
        PUBLIC test.h
    )
endif()

This should make your CMakeLists.txt files easier to maintain than wrangling variables.

Stephen Newell
  • 7,330
  • 1
  • 24
  • 28
  • 1
    Thanks. I tend to still use many of the techniques I learned when I started using CMake in 2008. I will have to remember this the next time I use this technique which in my case I do from time to time want conditional inclusion of source files and factories. – drescherjm May 05 '21 at 18:11
  • 1
    @drescherjm - I was in the same boat until a few years ago. It's a mind shift for sure, but I've found it far cleaner than the legacy style once I was willing to drink the kool-aid :) – Stephen Newell May 05 '21 at 18:13
4

Instead of using an if block, you can also constrain the sources with a generator expression:

add_executable(${TARGET} PUBLIC
   main.cpp
   mainwindow.cpp
   mainwindow.h
   mainwindow.ui
   $<$<PLATFORM_ID:Windows>:
       test.c
       test.h
  >
)

This approach also works with the target_sources command, if you prefer.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
3

You can use a variable for your source file list and append to that variable the OS specific files similar to this:

set( MY_SOURCES 
     main.cpp
     mainwindow.cpp
     mainwindow.h
     mainwindow.ui
)

if (WIN32) 
SET( MY_SOURCES ${MY_SOURCES} 
     test.c
     test.h
)
endif()

add_executable(${TARGET} ${MY_SOURCES})
drescherjm
  • 10,365
  • 5
  • 44
  • 64