【问题标题】:How to detect OS without directive ifdef?如何在没有指令 ifdef 的情况下检测操作系统?
【发布时间】:2020-09-24 09:47:11
【问题描述】:

我必须在 Linux 或 Windows 上重置系统日期和时间。 如何在不使用ifdefif defined 的情况下检查操作系统?

【问题讨论】:

  • 你使用的是什么构建系统?
  • 即使您检测到没有任何ifdef 的操作系统,您打算如何使用没有任何ifdef 的操作系统专用API?
  • 为什么你不能使用 ifdef 以及你打算在不使用 ifdef 的情况下做什么特定于操作系统的事情?
  • 你可能做不到。想想奇怪的操作系统,比如netbsdSolarisGNU hurd
  • 简短的回答是你不能。如果您不检查特定的宏(无论是由您的编译器设置还是在可以检测操作系统并相应地为您的构建定义宏的构建脚本中设置),您将依赖于其他一些(C++ 中的非标准)库函数或程序来检测操作系统。但是,要使用这样的库函数或程序,您需要检查操作系统以确定该库函数或程序是否可用。到那时,论证就变成了无限递归(就像老儿歌“桶里有个洞”)。

标签: c++


【解决方案1】:

使用 CMake,您可以使用 generator expressions 有条件地将文件添加到目标。这样,您就可以在文件中隔离任何特定于平台的代码,并在构建规范中使用它们,如下所示。

add_executable(reset-time
    $<$<PLATFORM_ID:Darwin>:resettime-macos.cpp>
    $<$<PLATFORM_ID:Linux>:resettime-linux.cpp>
    $<$<PLATFORM_ID:Windows>:resettime-windows.cpp>)

正如@eeroika 在 cmets 中指出的那样,一个不错的选择是

add_executable(reset-time
    resettime-$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>.cpp)

因为在将您的项目移植到新系统时不需要调整(CMakeLists.txt),您可以更早地捕获丢失的实现文件,即在链接之前。

【讨论】:

  • 我不能使用 2 个文件,只有一个。
  • @lubgr 我认为你不应该删除答案——因为虽然它可能对 OP 没有用(考虑到他们的特定限制),但它似乎对其他人仍然有用从谷歌搜索或其他任何东西中遇到问题和答案的未来。你不觉得吗?或者,另一方面,如果您认为问题本身非常特定于 OP 的情况,并且不太可能是其他人会遇到的问题,那么是的,在这种情况下,我想您可能会考虑删除答案。
  • @sideshowbarker 感谢您的评论。我想我应该留下它,以备将来参考。
  • @alexander.sivak 关于 “我不能使用 2 个文件,只有一个” 约束,您应该编辑/更新问题以明确提及该约束。否则,您可能会浪费其他人的时间,他们努力帮助找到答案,直到后来才知道您有其他秘密/惊喜限制。
  • 或者:resettime-$&lt;LOWER_CASE:${CMAKE_SYSTEM_NAME}&gt;.cpp 这样做的好处是如果程序移植到新系统,CMake 列表不需要更改。此外,您将收到有关丢失文件的错误,而不是未定义的链接器错误。
【解决方案2】:

您可以根据要编译的操作系统为编译器设置全局宏定义。例如-D IS_WINDOWS=1。然后您可以使用#if IS_WINDOWS 而不是#ifdef。我不知道为什么这会有用,但它达到了你的要求。

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2011-09-12
    • 2012-03-19
    • 2017-04-17
    • 2015-09-01
    相关资源
    最近更新 更多