5

对于我的一些类,每个操作系统都有不同的实现。
我的源结构是这样的:

  • 包括/AExample.h
  • 包括/windows/WindowsExample.h
  • 包括/linux/LinuxExample.h
  • src/AExample.cpp
  • src/windows/WindowsExample.cpp
  • src/linux/LinuxExample.cpp

A* 类是特定实现的接口

我当前的构建系统是 cmake - 但目前它只能构建 linux 版本。

在 windows 构建中,我只需要包含 windows/* 文件,在 linux 上只需要包含 linux/* 文件

我需要

  • 仅包含与我当前构建相关的文件
  • 当我需要 AExample 的实例时选择正确的实现

您可以推荐哪些技术以专业的方式实现这一点?

4

3 回答 3

9

这在 CMake 中相当容易。

只需让您的 CMakeLists.txt 文件检查平台,并根据需要添加适当的文件或包含适当的子目录。

基本语法是:

IF(WIN32)
    # Do windows specific includes
ELSEIF(UNIX)
    # Do linux specific includes
ENDIF(WIN32)
于 2009-07-09T18:48:41.507 回答
2

如果标头具有相同的名称但它们位于不同的层次结构中,您可以为您的编译器正确设置 -I(包含路径)标志。这比单独处理所有依赖于平台的包含要容易得多。

如果标头位于同一目录中和/或您想要自定义内容,您通常会在您的 C/C++ 代码中执行此操作:

#ifdef _WIN32
  .. include Win headers ..
#endif

#ifdef LINUX
  .. include Linux headers ...
#endif

除非您确定以后不需要切换构建系统,否则我不会推荐 cmake 特定的解决方案。

于 2009-07-09T19:14:17.383 回答
2

虽然我认为使用构建系统来处理跨平台文件是最好的,但是可以简单地编写源代码来通过预处理器来处理它。然而,这种非常常见、快速和肮脏的方法,即在代码中散布平台检查是有问题的,应该避免。

相反,您应该使用更高度结构化的方法来组织特定于平台的代码,以避免随着项目变大而出现问题。

平台特定代码应在文件级别明确标识:例如,使用每个平台的目录结构,并将所有平台特定源文件放在适当的目录中。源文件不应包含用于多个平台的代码或任何预处理器平台检查(但有一个例外)。此外,平台特定的源通常不应直接构建或#included. 相反,平台特定代码只能通过非平台特定源文件间接使用,这些源文件除了平台检查和#include平台特定文件之外什么都不包含。

示例源组织:

src/
  main.cpp
  foo.h
  foo.cpp
  windows/
    foo.cpp.inc
  posix/
    foo.cpp.inc

示例源内容:

// main.cpp
#include "foo.h"

int main() {
  foo();
}

// foo.h
void foo();

// foo.cpp
#if defined(_WIN32)
#  include "windows/foo.cpp.inc"
#elif __has_include(<unistd.h>)
#  include<unistd.h>
#  if defined(_POSIX_VERSION)
#    include "posix/foo.cpp.inc"
#  endif
#else
#  error Unknown platform
#endif

// windows/foo.cpp.inc
#include "foo.h"

#include <iostream>
#include <Windows.h>

void foo() {
  std::cout << "Windows\n";
}

// posix/foo.cpp.inc
#include "foo.h"

#include <iostream>
#include <unistd.h>

void foo() {
  std::cout << "POSIX\n";
}

Windows 构建和输出:

cl.exe /EHsc /W4 /WX src\main.cpp src\foo.cpp
main

视窗

Linux 构建和输出:

g++ -Wall -Wextra -Werror -Isrc src/main.cpp src/foo.cpp
./a.out

POSIX

当不同平台的代码可以合理地共享相同的文件组织时,上面示例中显示的方法非常有效。如果不同平台的代码差异很大,以至于您希望每个平台都有不同的文件结构,那么使用这种技术会更加困难,并且转向使用构建系统来管理不同平台的代码会变得更加明显。

也可以将这种技术与构建系统混合使用;跨平台共享文件结构的代码可以使用它,而不同平台特有的模块可以由构建系统处理。

于 2015-07-08T21:42:54.167 回答