How to include "WIN32" in an "add_executable()" command only on Windows?

I currently have the following block of code in my CMakeLists.txt file. What I’d like to be able to do is have just one “add_executable()” command and still have the “WIN32” keyword included only on Windows.

if(${WIN32})
	add_executable(minesweeper WIN32 minesweeper.rc ${SOURCE_FILES})
elseif(${LINUX})
	add_executable(minesweeper ${SOURCE_FILES})
endif()

I tried using a generator expression, but got an error about CMake being unable to find a source file named “WIN32”. Is there any way I can replace the two “add_executable()” commands with just one?

There’s a few ways you could tackle this. Firstly, note that you can put WIN32 in the add_executable() call and it will be ignored by platforms other than Windows, so no need to make adding that conditional. That leaves the minesweeper.rc file. You could use a generator expression like so:

add_executable(minesweeper WIN32
    $<$<BOOL:${WIN32}>:minesweeper.rc>
    ${SOURCE_FILES}
)

The $<BOOL:${WIN32}> is needed because WIN32 might not be defined, and the $<expression:...> form requires the expression to evaluate to 1 or 0. If WIN32 isn’t defined, ${WIN32} would evaluate to an empty string, which fails that requirement. Wrapping it in $<BOOL:...> ensures the result is 1 or 0.

However, it’s probably simpler to avoid the generator expression altogether. Here’s how I would implement it:

add_executable(minesweeper WIN32 ${SOURCE_FILES})
if(WIN32)
    target_sources(minesweeper PRIVATE minesweeper.rc)
endif()

As a final note, you haven’t shown how you’re populating the SOURCE_FILES variable. A common pattern used in tutorials is to populate such a variable using file(GLOB). Don’t do that, the docs make clear that’s not a suitable pattern. Explicitly list out each file, and you can do that directly in the call to add_executable(). You don’t gain anything by putting such a list in a SOURCE_FILES variable.

1 Like

I was populating the SOURCE_FILES variable by listing out each file. I put it in a variable so I could include the same set of files in each add_executable() command. The information you provided enabled me to get rid of that variable, though.