创建/组织可移植的C ++库

时间:2012-07-23 11:24:35

标签: c++ linux portability bitbucket

我不确定我组织我的图书馆的方式是组织它的最优雅方式。我主要关注的是为我所针对的所有系统(保持可移植性)编写所有我编译/运行的代码,并使每个系统保持最新。

例如: 我不确定使用__declspec(dllexport / dllimport)会用于Mac还是Linux。我认为不是,但我不知道Mac / Linux的等价物是什么。或者另一个例子可能是调用特定的操作系统函数,我试图避免这些函数。但是,诸如:以精确的方式测量事物发生的时间*确实需要我调用OS特定的功能。

*就像准确地获取用户的时间一样(低至微/毫秒)。

我目前(可能更多未来)的系统是Mac,Windows和Linux。但测试代码为每个系统编译(并正确运行)似乎只是浪费时间。目前,我提议这样做的方式,要求我为每个系统制作一个单独的项目。即我为Windows创建一个Visual Studio项目,为Mac创建一个Xcode项目,并使用Linux命令行或使用其他IDE。

好的,所以我组织事情的主要问题是:
1.时间消耗,如为所有系统创建项目并保持每个单独的项目,为每个系统更新。
2.了解我需要使用的所有IDE /编译器

请注意,我之前从未真正使用 * Linux,我正在考虑切换。我唯一关心的问题是找到合适的工具供我使用,找到适合我的合适的发行版,满足我的需求。如果有经验丰富的Linux人员可以指导我,或者给我一些关于是否切换的建议,我将非常感激。

我非常喜欢Visual Studio,现在它已经是我的主要IDE了。对于Linux,我只是不确定是否要抛弃Visual Studio;因为我不知道可用于Linux的工具是否能够完成Visual Studio的功能。我的意思是,它与Visual Studio一样友好。我害怕学习如何使用Linux的工具,我只是不确定它是否值得这样做。时间不是这个图书馆的主要因素,我有充足的时间,我还很年轻,并决心将我的职业作为未来的职业。

*我之前使用过它,但我从来没有用它取代它。

我目前在BitBucket上托管我项目的所有源代码,但目前我只在我的仓库上有RAW代码。没有项目文件或任何其他工具来编译它,只有代码和自述文件。我正在考虑使用Makefiles,因为它们看起来很受欢迎。但我以前从未制作过Makefile,不要误会我的意思,我愿意学习。我只是不确定从哪里开始。我听说人们使用CMake创建可移植的库,例如SFML和Ogre3D。我已经使用CMake构建了几个库,但我不知道如何使用它来创建我自己的库以生成我的项目/生成文件。我应该学习并将CMake与我的图书馆合并,还是有更好的选择?

修改

我的目标不是为使用GUI的实际软件编写库。我的目标主要是写 游戏

3 个答案:

答案 0 :(得分:3)

1 - 提升。 Boost将比您想象的更有助于您的便携性。它唯一真正的关键点是,不管你信不信,OS X。

2 - 使用CMake。它集成了Visual Studio项目文件作为构建工具,您可以将大部分不同平台的编译voodoo放在那里。

3 - 如果您正在认真编写可移植库,请考虑使用C语言编写C语言包装,或者将其设置为仅限标头,或者提供源代码。使它成为一个共享或静态可链接的库并不意味着它会发挥出色。名称错误会导致不一致,这会让你大吃一惊。

4 - 始终明确每个变量中的位数。

5 - 使用git。它将允许您非常轻松地为存储库设置一个糟糕的本地服务器,并且可以非常快速地传输MSVC会令人烦恼的那种巨大变化

可以讨论有关跨平台开发的更多最佳实践。所有这些建议并不适用于所有情况;我有一个非常代码密集的Linux / Windows库,我几乎完全在MSVC2k10中进行编码,主要是在Linux中进行构建/测试,并且它远不及仅限标题。

编辑回应评论:

建议使用git,因为我觉得它很容易在本地使用和管理。我之前使用svn并喜欢它,我不会真正支持任何其他人,但可能有很多很好的。

在第3点阐述, 一个C包装器可以使任何人都可以使用你的库 - FORTRAN开发人员,Ruby,甚至Java。 否则,您通常必须具有类似的编译器版本才能正确链接,并且它只链接到其他C ++代码,在DLL的情况下,并且仍然存在版本问题。这是C ++遗留下来的最愚蠢的问题之一,检查维基百科上的“名称修改”。有一个原因是广泛使用的库是用C语言编写的,或者有C包装器,比如libz,openssl等。

还有其他优点。跨动态库的异常传播不存在;对于静态库,它可能是不一致的或不存在的。

您会发现最广泛使用的C ++库主要是仅限标头,如Boost。只有头文件库通过以相对直观的方式将所有代码直接放入项目中来解决许多问题,现代编译器仍然可以优化掉与之相关的额外编译时间(但肯定不是全部)。

总而言之,如果没有C包装器或只有标头,它肯定是可能的,它只是烦人且非常麻烦。 DLL地狱及其Linux等价物仍然存在。

您还询问了Boost。那要看。如果您正在分发源代码,那么您当然必须使用您的代码分发Boost /让人们安装它。让人们安装库以编译其他库或使用程序是常见的做法。想想DirectX的特定版本如何附带游戏作为示例。

但是,如果您要分发库的二进制版本,静态链接Boost将消除任何包含它的需要,只要您小心地将Boost标题保留在库的外部部分之外。这是你开始在C ++头文件中看到像void *指针这样的东西;不幸的是,C ++编译和库分发的一些缺点的不幸副作用。

答案 1 :(得分:1)

就个人而言,我会利用像Qt这样的框架,因为它非常便携,它确实抽象了很多操作系统功能(文件,计时,线程,网络),而且你得到了一个体面的免费IDE(Qt Creator),也是可移植的,可在Windows,OS X和任何运行Qt的Unix风格上运行。它会给你最低的进入门槛。 Qt Creator可以利用Visual Studio编译器和CDB调试器(如果可用)。

需要使用OpenGL来使用Qt,事实上你并没有绑定任何特定的图形子系统。 Qt仅在Qt 5中“使用”OpenGL用于Qt Quick 2图形后端。 Qt 4不需要它,也不需要Qt Quick 1(即使在Qt 5中!)。

您可以使用任何您喜欢的2D或3D框架将图像和其他内容推送到屏幕。 Qt擅长的是创建游戏中经常需要的2D图像 - 菜单,配置屏幕,HUD等。有很多控件和绘图原语,Qt可以很容易地用于您的目的。

Qt还允许您使用功能相当强大的模型视图和网络框架,因此您可以合理轻松地生成实时更新的服务器或客户端列表。

当然,Qt和DirectX之间需要少量的填充码。在输出端,您通常最终在Qt中使用QImage,然后使用DirectX,SDL,OpenGL等将其推送到屏幕。在输入端,您需要在主游戏循环中调用qApp->processEvents(),并且需要使用qApp->postEvent(...)将用户输入事件从DirectX等发布到Qt的事件队列。只有当DirectX主循环消耗所有Windows消息并且不允许标准winapi / win32代码(Qt的Windows事件调度程序)看到它们时,才需要这样做。我没有太多关注DirectX,所以其他人可以随意提供详细信息。

答案 2 :(得分:1)

CMake是个不错的选择。你可以学习使用它。阅读教程:
http://www.cmake.org/cmake/help/cmake_tutorial.html

但是,如果你的目标只是Linux和Windows。在您的情况下(小型/平均第一个多平台项目),维护2个独立的构建系统可能没问题。

  • 在Linux上,使用Make。它是标准的并且有一个非常好的参考手册:
    http://www.gnu.org/software/make/manual/make.html

  • 在Windows上。使用您的IDE项目文件,无论是Visual,DevC ++还是其他。这是最简单的方法。

最重要的是,可以轻松地在不同平台上测试您的库/软件。在桌面上安装虚拟机。或者至少将您的库编译成Cygwin。

一旦你回到stackoverflow,我们会帮助你!