CMAKE_SYSTEM_NAME versus predefined variables

When working with CMake, it’s common to execute specific commands depending on the platform and operating system detected. During my research across various internet sources, I’ve encountered two commonly used snippets:


Method 1:

if(CMAKE_SYSTEM_NAME MATCHES "Windows")

	# WINDOWS
    
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
   
	# APPLE
   
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")

    # LINUX

endif()

Method 2:

if(WIN32)
  
  # WINDOWS

elseif(APPLE)
  
  # APPLE

elseif(LINUX)
  
  # LINUX

endif()

What is the difference between these two methods, and why is the first one mostly preferred over the second one?

There are at least a couple of important differences:

  • The LINUX variable is only defined with CMake 3.25 and later, whereas testing if CMAKE_SYSTEM_NAME matches Linux will work for all CMake versions.
  • With CMake 3.14 and later, CMAKE_SYSTEM_NAME can be set to iOS, tvOS, or watchOS. CMake 3.28 also added support for the value visionOS. All of these will have the APPLE CMake variable set to true.
3 Likes