CMake选项禁用特定平台的特定文件的编译

时间:2013-01-26 07:17:43

标签: c++ cross-platform cmake

我正在使用CMake来定义我的项目。我的目标是在所有平台上轻松访问特定于平台的文件,以便进行编辑,搜索,浏览和源代码控制。

我目前在cmake描述中分隔了特定于平台的文件。我的CMakeLists.txt文件如下所示:

 Foo.hpp
 ${platform_directory}/Foo.cpp

然后在磁盘上我有这样的事情:

 Foo.hpp
 win
  `- Foo.cpp 
 osx
  `- Foo.cpp 

生成的项目文件中的内容如下:

 Foo.hpp
 Foo.cpp (platform-specific version)

这对于编译器来说是完美的,但这意味着开发人员缺少针对非本机平台特定文件的IDE工具。

我正在寻找的是这样的(在Xcode中):

 Foo.hpp
 Foo.cpp (OS X version)
 win
  `- Foo.cpp (file type set to plain text)

或者在Visual Studio中:

 Foo.hpp
 Foo.cpp (Windows version)
 osx
  `- Foo.cpp (build action set to none)

关于如何设置这样的东西的任何想法都可以设置CMake?

2 个答案:

答案 0 :(得分:3)

一种方法是添加一个没有构建规则的自定义目标,专门用于保存不属于给定平台构建的文件; 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()

另一种选择(可能更接近你想要的,但更多的是“hacky”)是将所有文件添加到目标,但将构建不需要的文件标记为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()

答案 1 :(得分:1)

technique建议的HEADER_FILE_ONLY Fraser效果很好,但明确配置应该在哪个平台上编写哪些文件会变得乏味。

给出CMake函数如下:

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()

我们可以通过后缀来控制特定于平台的来源。例如:

set(all_sources
   Foo.hpp
   FooWin32.cpp # windows-specific
   FooApple.cpp # apple-specific
)

DisableCompilingPlatformSpecificSources("${all_sources}")

add_executable(foo ${all_sources})

这与gyp处理platform-specific files的方式非常相似,可以根据需要轻松扩展以支持其他后缀。