I am using CMake to define my projects. My goal is to have platform-specific files easily accessible for editing, searching, browsing, and source control with across all platforms.
I currently have platform-specific files separated in the cmake description. My CMakeLists.txt file looks something like the following:
Foo.hpp
${platform_directory}/Foo.cpp
Then on disk I have something like this:
Foo.hpp
win
`- Foo.cpp
osx
`- Foo.cpp
Which in the generated project file looks like:
Foo.hpp
Foo.cpp (platform-specific version)
This is perfect for the compiler, but it means that developers lack IDE tooling for non-native platform-specific files.
What I am looking for is something like this (in Xcode):
Foo.hpp
Foo.cpp (OS X version)
win
`- Foo.cpp (file type set to plain text)
Or in Visual Studio:
Foo.hpp
Foo.cpp (Windows version)
osx
`- Foo.cpp (build action set to none)
Any ideas on how something like this can be setup CMake?
One way would be to add a custom target with no build rules, specifically to hold the files which aren't part of the given platform's build; e.g.
if(WIN32)
add_library(Foo Foo.hpp win/Foo.cpp)
add_custom_target(NonWindows SOURCES osx/Foo.cpp)
source_group("osx" osx/Foo.cpp)
else(APPLE)
add_library(Foo Foo.hpp osx/Foo.cpp)
add_custom_target(NonApple SOURCES win/Foo.cpp)
source_group("win" win/Foo.cpp)
endif()
Another option (perhaps closer to what you want, but a bit more "hacky") is to add all the files to the target, but mark the ones not required for the build as HEADER_FILE_ONLY
:
add_library(Foo Foo.hpp win/Foo.cpp osx/Foo.cpp)
if(WIN32)
set_source_files_properties(osx/Foo.cpp PROPERTIES HEADER_FILE_ONLY TRUE)
source_group("osx" osx/Foo.cpp)
else(APPLE)
set_source_files_properties(win/Foo.cpp PROPERTIES HEADER_FILE_ONLY TRUE)
source_group("win" win/Foo.cpp)
endif()
The HEADER_FILE_ONLY technique suggested by Fraser works great, but explicitly configuring which files should be complied on which platform gets tedious.
Given a CMake function as follows:
function (DisableCompilingPlatformSpecificSources file_list)
foreach(file ${file_list})
if (
((${file} MATCHES "^(.*)Win32\\.cpp") AND NOT WIN32) OR
((${file} MATCHES "^(.*)Unix\\.cpp") AND NOT UNIX) OR
((${file} MATCHES "^(.*)Apple\\.cpp") AND NOT APPLE)
)
set_source_files_properties(
${file}
PROPERTIES HEADER_FILE_ONLY TRUE
)
endif()
endforeach()
endfunction()
We can control platform-specific sources by means of their suffix. For example:
set(all_sources
Foo.hpp
FooWin32.cpp # windows-specific
FooApple.cpp # apple-specific
)
DisableCompilingPlatformSpecificSources("${all_sources}")
add_executable(foo ${all_sources})
This is quite similar to how gyp handles platform-specific files and can be easily extended to support additional suffixes as needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With