{"id":116,"date":"2012-04-13T18:46:22","date_gmt":"2012-04-13T16:46:22","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=116"},"modified":"2013-07-23T11:07:28","modified_gmt":"2013-07-23T09:07:28","slug":"the-suggested-dependencies-problem","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2012\/04\/13\/the-suggested-dependencies-problem\/","title":{"rendered":"The suggested dependencies problem"},"content":{"rendered":"<p>Optional runtime dependencies (or\u00a0\u00absuggested dependencies\u00bb) are one of\u00a0the\u00a0late problems we&#8217;re facing in\u00a0Gentoo. There&#8217;s definitely a\u00a0need for\u00a0some standard solution, and\u00a0it&#8217;d be great to\u00a0put it in\u00a0the\u00a0next EAPI. Sadly, there&#8217;s no\u00a0consensus how to\u00a0solve it.<\/p>\n<p><!--more--><\/p>\n<h2>The optional dependencies problem<\/h2>\n<p>Gentoo has a\u00a0very neat solution for\u00a0handling optional dependencies and\u00a0optional features, probably ever since the\u00a0beginning. It is\u00a0called \u00abUSE flags\u00bb and\u00a0they work very well with the\u00a0\u00abtraditional\u00bb optional dependencies. By\u00a0that, I\u00a0mean optional dependencies which are both build- and\u00a0run-time.<\/p>\n<p>Such a\u00a0dependencies have to be pulled in before the\u00a0build process starts, and\u00a0usually require passing specific options in\u00a0the\u00a0configure phase. What&#8217;s important, both enabling and\u00a0disabling features requires rebuilding the\u00a0program in question because of\u00a0code branches being switched. Thus, it&#8217;s perfectly fine if\u00a0changing USE flags implies rebuilding the\u00a0package.<\/p>\n<p>Sadly, when it comes to optional runtime dependencies, USE flags are not a\u00a0perfect solution. \u00abSwitching\u00bb such a\u00a0dependency doesn&#8217;t require rebuilding the\u00a0program anymore. It&#8217;s usually not\u00a0even switching \u2014 the\u00a0program can determine in\u00a0runtime whether a\u00a0particular dependency is\u00a0available, and\u00a0either enable or\u00a0disable respective features. Simple like that.<\/p>\n<p>If\u00a0one decides to\u00a0use USE flags for that, they become partially meaningless. Unless flags start stripping off the\u00a0code (which is a\u00a0bad idea), feature availability is dependency- rather than flag-based. So, <code>USE=-ssl<\/code> is irrelevant if, say, <code>pyopenssl<\/code> is installed. What&#8217;s even worse, flag imply needless rebuilding of such packages just to pull\u00a0in an\u00a0additional dependency.<\/p>\n<h2>The\u00a0simple hack \u2014 pkg_postinst() messages<\/h2>\n<p>The\u00a0simplest solution right now is just listing the\u00a0suggested dependencies in\u00a0<code>pkg_postinst()<\/code> messages. Combined with <code>has_version<\/code> helper, those messages can give a\u00a0pretty nice output, pointing out already installed packages \u2014 just take a\u00a0look at\u00a0<code>sys-apps\/systemd<\/code> ebuild.<\/p>\n<p>Of\u00a0course, it&#8217;s not a\u00a0real solution, rather relying on user doing the\u00a0hard work. The\u00a0biggest disadvantage is that the\u00a0dependencies are often going to end up in\u00a0<em>@world<\/em>. And\u00a0then, if\u00a0user decides to\u00a0unmerge our package, portage is unable to find and\u00a0unmerge them as\u00a0well.<\/p>\n<h2>The\u00a0SDEPEND solution<\/h2>\n<p>A pretty common idea is to\u00a0establish a\u00a0new variable called <code>SDEPEND<\/code> (for\u00a0\u00absuggested\u00bb). Such a\u00a0variable would simply list relevant dependencies, and\u00a0let portage handle the\u00a0UI part somehow. It is a\u00a0minimalistic solution, quite consistent with other parts of\u00a0PMS. Sadly, it has a\u00a0few big shortcomings.<\/p>\n<p>First, using our current dependency syntax, you can&#8217;t specify that a\u00a0particular feature requires more than one package; in\u00a0other words, that two or\u00a0more suggested dependencies are\u00a0supposed to be\u00a0pulled\u00a0in together. Of\u00a0course, solving this one would be\u00a0pretty easy \u2014 e.g.\u00a0by\u00a0allowing grouping them with parantheses.<\/p>\n<p>A\u00a0much more important issue is describing what particular dependencies do. Although sometimes this could be guessed by\u00a0package descriptions pretty well, usually a\u00a0more friendly text would be great. So, we end up having to implement that somehow.<\/p>\n<p>And\u00a0that&#8217;s usually when Ciaran comes in\u00a0with ugly exherbism <code>DEPENDENCIES<\/code>. Sure, it solves most of the\u00a0issues pointed out here but, hell, do\u00a0we really want such a\u00a0thing? Isn&#8217;t dependency syntax obscure enough already?<\/p>\n<p>And\u00a0it&#8217;s all rather dependency-oriented. In\u00a0other words, package comes first, then goes the\u00a0feature description. \u00abPass <code>dev-python\/pyopenssl<\/code> or <code>dev-python\/python-gnutls<\/code> to\u00a0enable secure connections support\u00bb. I\u00a0don&#8217;t think that&#8217;s the\u00a0most user friendly solution.<\/p>\n<h2>The\u00a0USE flag solution<\/h2>\n<p>Another solution is\u00a0brining a\u00a0new category of\u00a0USE flags. It&#8217;s not important whether they would be\u00a0specified using a\u00a0special variable, common <code>USE_EXPAND<\/code> or\u00a0another magical features. In\u00a0fact, that could be a\u00a0thing totally separate from USE flags. The\u00a0point is\u00a0that some of\u00a0the\u00a0package flags would be runtime-switchable.<\/p>\n<p>Unlike traditional USE flags, such flags wouldn&#8217;t be\u00a0stored in\u00a0vdb. They would be\u00a0evaluated in\u00a0place instead, using <code>package.use<\/code> or\u00a0similar files, and\u00a0the\u00a0dependency tree would use current state of\u00a0such flags. Of\u00a0course, they would be allowed for\u00a0<code>RDEPEND<\/code> (<code>PDEPEND<\/code>) use only.<\/p>\n<p>Why reuse USE flags for\u00a0that? Because it&#8217;s the\u00a0most user-friendly solution. User doesn&#8217;t have to\u00a0learn anything new. He\/she enables a\u00a0flag, does <code>emerge -vDtN @world<\/code> and\u00a0notices that new dependencies are pulled in but\u00a0the\u00a0package doesn&#8217;t have to be\u00a0rebuilt for that.<\/p>\n<p>If we just add some additional magic for\u00a0regular USE flags, enabling run-time dependant SSL support could be\u00a0exactly the\u00a0same as\u00a0enabling build-time one \u2014 even using the\u00a0same <code>USE=ssl<\/code>.<\/p>\n<p>And\u00a0we could basically even give \u00abbackwards\u00bb support for\u00a0older EAPIs. Package managers not supporting the\u00a0new feature would simply treat runtime-switchable USE flags as\u00a0regular USE flags, requiring rebuilds of\u00a0the\u00a0package.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Optional runtime dependencies (or\u00a0\u00absuggested dependencies\u00bb) are one of\u00a0the\u00a0late problems we&#8217;re facing in\u00a0Gentoo. There&#8217;s definitely a\u00a0need for\u00a0some standard solution, and\u00a0it&#8217;d be great to\u00a0put it in\u00a0the\u00a0next EAPI. Sadly, there&#8217;s no\u00a0consensus how to\u00a0solve it.<\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/116"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=116"}],"version-history":[{"count":5,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/116\/revisions"}],"predecessor-version":[{"id":212,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/116\/revisions\/212"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}