{"action":"opened","issue":{"url":"https://api.github.com/repos/haskell/cabal/issues/3064","labels_url":"https://api.github.com/repos/haskell/cabal/issues/3064/labels{/name}","comments_url":"https://api.github.com/repos/haskell/cabal/issues/3064/comments","events_url":"https://api.github.com/repos/haskell/cabal/issues/3064/events","html_url":"https://github.com/haskell/cabal/issues/3064","id":127365581,"number":3064,"title":"Per-component interface for Setup","user":{"login":"ezyang","id":13564,"avatar_url":"https://avatars.githubusercontent.com/u/13564?v=3","gravatar_id":"","url":"https://api.github.com/users/ezyang","html_url":"https://github.com/ezyang","followers_url":"https://api.github.com/users/ezyang/followers","following_url":"https://api.github.com/users/ezyang/following{/other_user}","gists_url":"https://api.github.com/users/ezyang/gists{/gist_id}","starred_url":"https://api.github.com/users/ezyang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ezyang/subscriptions","organizations_url":"https://api.github.com/users/ezyang/orgs","repos_url":"https://api.github.com/users/ezyang/repos","events_url":"https://api.github.com/users/ezyang/events{/privacy}","received_events_url":"https://api.github.com/users/ezyang/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-01-19T04:54:42Z","updated_at":"2016-01-19T04:54:42Z","closed_at":null,"body":"This ticket details a design for a per-component interface for Setup. Such an interface would fix #3049 (nix-local-build cabal-install would be able to request recompilation of only components that changed, rather than all components), #2802 (you could configure an individual component), #2780 (you would have per-component copy), #2775 (you can just build one component at a time), #2725 (you can configure each component with different dependencies), #2623 (you would parallelize over calls to build components, not packages), #2071 (you would have per-component test) and #1575 (you could just configure one component). I also happen to need it for Backpack.\r\n\r\n## The existing package interface\r\n\r\nThe interface for `Setup` was historically defined by the Cabal specification: https://www.haskell.org/cabal/proposal/pkg-spec.pdf It defined that a Setup script must satisfy the following command line interface:\r\n\r\n```\r\n./Setup configure [flags]\r\n./Setup build\r\n./Setup copy # not in the original spec but what we use today\r\n./Setup register\r\n./Setup clean\r\n./Setup test\r\n```\r\n\r\nThese commands are *package* oriented and, left to their own devices, will build your entire package.\r\n\r\n## Building components using the existing interface\r\n\r\nOver time, we've grown more flags and modes, e.g. `cabal build foo` which builds just the `foo` component. Thus, to a certain degree, per-component builds can be simulated in the following way:\r\n\r\n* `./Setup configure` must still be run once, with ALL components you may be interested in building enabled at this time.\r\n* `./Setup build foo` then builds just the `foo` component\r\n* `./Setup register` if you built the library component (because that's the only component that can get registered, pre #3022 )\r\n* `./Setup copy` could be extended to copy just individual components, but it doesn't really support it, see #2780. Teaching copy to copy individual components should be relatively simple, but nobody has done it.\r\n\r\nBut there are a few deep assumptions which are a bit harder to deal with in the current world:\r\n\r\n* `./Setup configure` must configure all the components you want to build in a single `dist` at once. If you decide to enable another component, Cabal redos the configuration step. If an executable and a test-suite share a dependency, it must be picked consistently between the two.\r\n* `./Setup` scripts DO support building to different dist directories, so you might imagine making a separate `dist` directory per component. But you quickly run into a different problem: many components in a package may depend on the library, which you would like to share between compilations. If you are able to install the library, no problem, but if you are build-rebuilding inplace you need to make sure the separate components can see the inplace library you built in a different dist-directory. (Also, there is no way to not build the library, c.f. #2775).\r\n\r\n## The proposed interface\r\n\r\n(to be written)"}}