草庐IT

c++ - 具有许多第三方依赖项的大型跨平台 C++ 项目在磁盘上的物理布局

coder 2024-02-03 原文

我正在重组 large cross-platform C++ project 的物理(磁盘上)布局具有许多第三方依赖项,使用 CMake 构建。

由于我们需要支持 Windows,一个没有完善的包管理器的平台,我们很久以前就决定将我们依赖的第三方库包含在源代码树中。但是,在我们支持的其他平台(例如 Linux 和 Mac OS X)上,这些第三方库中的许多都以软件包的形式提供或已经存在于系统中,并且很容易被 CMake 找到。

目前项目布局如下:

root/
    src/
        3rd-party-lib1/       (build system modified to output to build/)
        3rd-party-lib2/       (build system modified to output to build/)
        project-module1/      (our own code)
        project-module2/      (our own code)
    build/                    (CMake is invoked from here)
        3rd-party-lib1-bin/
        3rd-party-lib2-bin/

第三方库已经过调整,因此在构建时,它们将二进制文件输出到 root/build/<lib>/ .

这种布局的问题是多方面的:

  • 第三方库不再是 100% 原创。这使得更新它们比所需的稍微困难一些。
  • src/目录包含我们自己的代码和第三方代码的混合,这令人困惑。
  • src/目录非常大。因为src/包含第三方库,与原始源代码的实际数量相比非常大,使得备份我们自己的代码比所需的稍微复杂一些(我们不能再只归档整个 src/ 目录)。
  • 项目存储库 (Git) 非常大,因为包含第三方库(其中可能包含大量非源文件,例如文档、测试数据等),并且每次我们更新它们时它都会变大。不幸的是,没有办法回到这里,除非我们决定用一个新的存储库重新启动(不幸的是丢失了整个提交历史)。
  • 在 Linux 或 Mac OS X 上构建项目的用户根本不需要其中包含的许多第三方库(例如 zlib、libpng),尽管它们大大简化了 Windows 用户的操作。

另一种布局如下:

root/
    3rdparty/
        3rd-party-lib1/       (100% original, contains built artifacts)
        3rd-party-lib2/       (100% original, contains built artifacts)
    src/
        project-module1/      (our own code)
        project-module2/      (our own code)
    build/                    (CMake is invoked from here)

我们的 CMake 文件需要修改以在每个库的正确位置查找第三方头文件和库。

在原生跨平台项目中处理第三方库的最佳实践是什么?哪种布局会为我们的开发人员在各自平台上带来最意想不到的构建体验?也欢迎现有项目成功布局的具体示例。

最佳答案

我的经验表明以下是最佳实践:

  • 当完全按原样使用第三方开源库时,在主 git 存储库中提交下载的压缩 tarball 的本地拷贝,以避免网络连接问题阻止软件构建。

  • 当第三方开源库几乎按原样使用,但需要进行调整时(这 在交叉编译时很常见:许多包需要对其配置步骤进行轻微调整),将压缩的 tarball 和“统一差异”补丁文件存储在主 git repo 中,并在 ExternalProject_Add 的 PATCH_COMMAND 步骤中应用补丁。

  • 当您的组织(将)对第三方开源库进行大量修改或扩展时,使用单独的 git 存储库来保存指向上游存储库的指针(当它也使用 git 时最简单,但上游svn 也可以管理)。将您组织的更改提交到与用于镜像上游的分支不同的分支。如果您愿意,您可以在主 git 存储库和这个 git 存储库之间引入子模块关系,不过因为 DOWNLOAD_COMMAND 可以直接从任意 git 存储库获取,所以从技术上讲没有必要这样做。

  • 通过将它们也存档在主 git 存储库中来处理针对单个目标平台的小型、不太常见的第三方专有二进制文件是合理的。但是,适用于各种平台、较大或经常演变的第三方二进制文件应存储在它们自己的 git 存储库中,并通过 DOWNLOAD_COMMAND 获取,如上所述。

关于c++ - 具有许多第三方依赖项的大型跨平台 C++ 项目在磁盘上的物理布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19616984/

有关c++ - 具有许多第三方依赖项的大型跨平台 C++ 项目在磁盘上的物理布局的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  5. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  6. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  7. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  8. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  9. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  10. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

随机推荐