C 和 C++ 语言是否已准备好应对 npm 危机
“我刚刚解放了我的模块” 在 node/javascript 社区引起了极大的担忧,并且是有理由的。
C 和 C++ 语言社区是否已准备好应对这样的问题?简短的答案是肯定的。问题在于,我们之所以做好准备,是因为我们并不像它们那样依赖于一个集中式存储库,该存储库托管着我们依赖的 99% 的现有开源库。所以我们还没有到那个地步。
有些人可能会争辩说这不是问题,但事实并非如此。我大量使用过 Maven(用于 Java)和 NPM(用于 Javascript),它们非常方便。在这些语言中处理依赖项比在 C 和 C++ 中简单得多。我不想就系统包管理器展开争论(它们不是解决方案,但那是另一篇文章的内容:)。
Conan 正试图填补这一空白。我认为这是一个很好的机会来解释一些关于它的设计决策,以及安全性和其他原因如何影响了 Conan 的当前设计。
允许删除包
有些人认为不应该允许删除包,即使是由作者删除也不行。这只是故事的一半,他们只关注自己作为包使用者而非创建者的角色。如果您已经是 Maven Central,这种方法可能有效,但请猜猜,对于一个年轻的项目来说,它并不适用。我们已经经历过:包开发者希望能够完全删除他们的贡献,如果不允许这样做,他们会非常不满。如果没有包创建者贡献,就没有包,平台的价值就微乎其微。因此,绝对有必要允许删除,否则平台永远无法获得足够的启动。但这本身并不是问题,如果能够有效地管理的话。
使用命名空间。
是的,我们(在 C++ 中)喜欢命名空间。它们是必要的,至关重要的。为什么有人会仅仅从包管理器中安装“string1.0”呢?因此,Conan 中的包通过包的名称和版本以及作者和通道来引用,类似于 Boost/1.60@boostorg/stable。因此,当您依赖它时,您就可以确定包的创建者。如果包的作者决定删除该包,则任何其他人都不能替换它。
conanfile.txt
[requires]
zlib/1.2.8@lasote/stable
[generators]
cmake
派生/复制依赖项
使用 Conan,有两种方法可以从其他人那里创建包
- 如果他们有一个包含包配方的存储库,只需克隆它并在您的用户名下导出它。您可以在本地或 CI 中生成自己的二进制文件,并上传您自己的配方和包。它们是完整的副本,不会受到原始源删除的影响。
git clone https://github.com/lasote/conan-zlib.git
cd conan-zlib
conan export anotheruser/mychannel
- 也可以使用“conan copy”命令复制/重命名现有的包,包括二进制文件。
conan copy zlib/1.2.8@lasote/stable anotheruser/mychannel
- 然后,只需更改命名空间。
conanfile.txt
[requires]
zlib/1.2.8@anotheruser/mychannel
[generators]
cmake
分布式方法
Conan 被设计为分布式的,因此,如果来自外部来源的包的来源或可用性令人担忧,设置您自己的 Conan 服务器非常简单。从其他来源(如 conan.io)读取您的依赖项,然后将它们上传到您自己的 Conan 服务器,这样您就可以独立于外部世界。
包配方和二进制清单
是的,工件必须有签名。现在,我们在每个包配方和每个包二进制文件中生成清单(包含每个文件 SHA 的文件列表)。我们使用这些清单来恢复失败的上传或检查上游更新。由于生成器提供了项目依赖项的路径,因此将检索到的清单与预定义的清单进行匹配应该不难。
ZMQ 示例包的 conanmanifest.txt
1458596605
lib/libzmq-mt-s-4_1_1.lib: 1852cee65e1676e1d93ccdfc501788b0
FindZeroMQ.cmake: 5054e9b947b5243b7ebc0c2fa652f7dd
include/zmq.h: 2330e48f210fc4771ea5d45c66905be3
conaninfo.txt: 7637eaae9c8bce1d5c3e053fd8c24dfb
include/zmq_utils.h: 2a2d13497628f0e24ab63cbe48d49aa4
我们认为,通过这些措施,Conan 已经做好了充分的准备,可以避免将来出现此类问题。这篇文章并不是要宣称我们有多好、多聪明或其他什么,只是分享一些我们的设计理念。您还有其他想法吗?贡献、建议?请告诉我们,或者更好的是,通过一些 pull request 加入我们的贡献者社区:D