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

Creating/Organising a portable C++ library

本文关键字:可移植 一个 C++ 创建      更新时间:2023-10-16

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

例如:我不确定使用__declspec(dllexport/dllimport)是否会用于Mac或Linux。我认为不是,但我不知道Mac/Linux的等价物是什么。或者另一个例子可能是调用特定的操作系统函数,我尽量避免这样做。然而,诸如:以精确的方式测量某件事发生需要多长时间*之类的事情确实需要我调用操作系统特定的函数。

*比如精确地获取用户的时间(精确到微/毫秒)。

我目前(也许在未来)的目标系统是Mac、Windows和Linux。但是,测试代码为每个系统编译(并正确运行)似乎只是浪费时间。和目前一样,我提议的方式要求我为每个系统制定一个单独的项目。也就是说,我创建了一个适用于Windows的Visual Studio项目,一个用于Mac的Xcode项目,并使用Linux的命令行或使用其他IDE。

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

请注意,我以前从未真正使用过*Linux,我正在考虑切换。我唯一关心的问题是找到适合我使用的工具,并找到适合我的Distro。如果有一个熟悉Linux的人能指导我,或者给我一些关于是否切换的建议,我将不胜感激。

我真的很喜欢Visual Studio,它已经成为我的主要IDE很长一段时间了。我只是不确定是否要放弃Visual Studio,转而使用Linux;因为我不知道Linux可用的工具是否能做Visual Studio能做的事情。我的意思是,它和Visual Studio一样对用户友好。我害怕学习如何使用Linux的工具,我只是不确定这样做是否值得。时间不是这个库的主要因素,我有足够的时间,我还很年轻,决心把编程作为我未来的职业。

*我以前用过它,但从未在Windows中更换过它。

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

编辑:

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

1-Boost。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。否则,通常必须有类似的编译器版本才能正确链接,并且它只会链接到DLL之外的其他C++代码,并且仍然存在版本控制问题。这是C++遗留下来的最愚蠢的问题之一,请查看维基百科上的"名称篡改"。广泛使用的库是用C编写的,或者有C包装器,如libz、openssl等,这是有原因的。

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

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

有了这些,当然可以只使用C包装器或头,这很烦人,也很麻烦。DLL地狱及其Linux等价物仍然存在。

你还问过Boost。这取决于情况。如果你正在分发源代码,那么你肯定必须随代码一起分发Boost/让人们安装它。让人们安装库以编译其他库或使用程序是常见的做法。举个例子,想想DirectX的特定版本是如何随游戏一起出现的。

然而,如果您正在分发库的二进制版本,那么只要您小心地将Boost标头排除在库的面向外部部分之外,针对Boost的静态链接将消除包含它的任何需要。这就是您开始在C++头中看到诸如void*指针之类的东西的地方;不幸的是,C++编译和库分发的一些缺点带来了不幸的副作用。

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

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

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

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

最重要的是,让在不同的平台上测试你的库/软件变得容易。在桌面上安装虚拟机。或者至少把你的库编译成Cygwin。

一旦你到了这里,就回到斯塔克维尔弗洛,我们会帮助你的!

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

不需要使用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,所以其他人当然可以随意地加入细节。