From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Mohsin Kaleem Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] Project out of sources compilation Date: Mon, 22 Apr 2024 22:20:32 +0100 Message-ID: <87il09hz6n.fsf@kisara.moe> References: <1fd527fc-9643-49d2-8fae-d7e7fd043fe1@gutov.dev> <87le5x34l6.fsf@gmail.com> <27rton4k4r6sacysluk7iikj57ai2tyiak4ldd5nzpts7thmhg@nriej75catir> <09a8189d-07e3-4bc5-a4f4-127dcdcec2d1@gutov.dev> <2bpiuffyzhqvirscyn5prs4rb6m5ito7xnwqvc53obm32isp3g@w73yut5uku4y> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="29952"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Ergus Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Apr 23 06:58:56 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rz8F5-0007ak-BX for ged-emacs-devel@m.gmane-mx.org; Tue, 23 Apr 2024 06:58:55 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rz8EL-0000OU-Aa; Tue, 23 Apr 2024 00:58:09 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rz1B2-0005An-7W for emacs-devel@gnu.org; Mon, 22 Apr 2024 17:26:16 -0400 Original-Received: from 119.ip-51-38-65.eu ([51.38.65.119] helo=mail.kisara.moe) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rz1Az-0000gx-Mz for emacs-devel@gnu.org; Mon, 22 Apr 2024 17:26:15 -0400 Original-Received: from mk-desktop (bcde7b88.skybroadband.com [188.222.123.136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (prime256v1) server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by mail.kisara.moe (Postfix) with ESMTPSA id D5454A2796; Mon, 22 Apr 2024 23:20:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kisara.moe; s=default; t=1713820832; bh=e1T4LzSKpYlEABsGxIATqPPPlZhKlZXTtrFfm5MfFfI=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=IWYyd1uVjw5KlP4R9Rgb+ckbcapEW1zl/Hjv+IjxD8qs1CrFXi7pN60jeo7zHDtfl eSgMCPkrXCpXgewAyBIC1S03d82lMCL8qubm4P5DUPAeZCJ6M20Q6sHE73FJ9v8OBg 3b9lgOkOZs9HwKMajkZY+kQ6I6rhMfwyr7FCJwNLF4kLqkgBkfa35srSFsEE04OE8z L6mB1KrYCGuWF88gWFlxtuMumWZTRFAlmjHRFlG3GiTq1VmKniZlKwkcgJbOXMOMgA 7I+2m3NrVjcrL//p97tD+OGcYm1bBqNxQ5Eo2WJR8aS+N4cnImv+qLpsJng+AE6D/P DlhtyQoYW+mvg== In-Reply-To: Received-SPF: pass client-ip=51.38.65.119; envelope-from=mohkale@kisara.moe; helo=mail.kisara.moe X-Spam_score_int: -6 X-Spam_score: -0.7 X-Spam_bar: / X-Spam_report: (-0.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RDNS_DYNAMIC=0.982, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Tue, 23 Apr 2024 00:58:07 -0400 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:317997 Archived-At: Ergus writes: Howdie howdie, I'm the maintainer of projection. Looks like it's a similar external package to what we're trying to formalize in Emacs core project.el . I'm just going to highlight 2 things which I think would help you Ergus. Ninja multi-config generators [1] which basically lets you configure a project for Debug, Release, ASAN, UBSAN, etc. simultaneously. And CMake presets [2] which is a standard for loading common configuration in CMake like build directories but also compiler flags, environment variables, etc. [1]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html [2]: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html I'll add my 2-cents on some of the discussed points. Firstly, I disagree with the goal of making the build directory option customizable in project.el itself. Most build tools I've encountered (including all supported by projection) take an extra flag to point to the build directory and I find this a nicer UX because it's easily inspectable and editable with `C-u M-x recompile`. I noticed projectile supported this feature of "run somewhere else" as well but it was only for one project type "meson" and even that has this option to move directories so I don't really see the value of complicating the interface to support it. Another pain point with a generalised "build-directory" option is that it's not generic for all possible commands. Configuration often runs before the build directory exists (because it creates it) so then you need an exemption for one command type but not another. I think the project-root as a standard location for commands to run is a good common default and changing it unless absolutely necessary is un-needed :-). Secondly I agree with Dmitry about defining an alternate orthoganal API to project.el for this. It probably belongs more in a project-types.el package. The motivation being that project.el is for more bare-bones mechanics, things like "am I in a project", "where is the root of the project", "show me all the files in this project". Project types is more "how do I build this project", "how do I test it", "what artifacts does it produce". The former is a set of functionalities which is relatively common and static across all projects, the latter is very specific to what kind of a project we're dealing with and how you interface with it. For example python projects probably don't have a configure step or build directory, node projects may treat "npm install" as a configure step but omit building, CMake projects support all steps through to packaging and installing. Things don't generalise well here. I think Ergus you've actually touched on a fun corner case. You've got a project with sub-projects and define a regex in a marker file to detect this. I'll admit I haven't touched on this before, I know you can have a CMake project with different sub-directories being considered their own projects and buildable independently, but I've never seen this practice in my day-to-day work. I'd be inclined to treat this as a project.el feature, something akin to git sub-modules. My only concern with it as a feature is its not trivial to check like git submodules. Basically every directory in a CMake project can have a CMakeLists.txt file and recursively searching upwards for one that might coincidentally also be a project root marker isn't ideal :-(. While we're discussing interfaces for this project-type abstraction I'll mention what I did for projection. In projection a project-type is an eioio class. It has some slots like :predicate to check if the current project matches that type and :build, :test, etc. for various project specific commands that can be run. The list of all actively checked-for project types is just a flat hook. I opted for this for 2 reasons: 1. It's easy to modify. Every project-type can be edited directly you can deregistered one from the monitored set of types by just removing it from the collection. 2. It enforces a general ordering concept which is important for determining a primary project type. I think moving the properties into a generic function though would just decouple them and make it harder to reason about and modify them. In regards to interactivity, I outsourced a lot to another package I maintain called compile-multi [3]. At its core its just a menu for predicates and compile commands. When predicate X, you have the option to choose command Y. I've plugged it into projection so that through it you can see project type specific options. For example in a CMake project this menu shows you all compilation targets and all CTest targets. Running a selected target will run the compile command that builds that target. If you want to permanently override one that runs with the standard projection-commands-build-project or projection-commands-test-project interactive commands (this is the same as setting what you're wanting to build going forward) I recommend using of embark [4]. What I normally do is run `M-x projection-multi-compile` narrow to the build or test target I care about and then run `M-x embark-act p c` (or p t for a test) and next time I run projection-commands-build-project it'll use that selected command. If I want to reset this to the project default I can use `M-x projection-cache-clear` which shows all cached project options and lets me select one or more to prune. Next time I run any command it'll be the default for the current project. [3]: https://github.com/mohkale/compile-multi [4]: https://github.com/oantolin/embark I think generalising this latter feature to a common interface will be tricky. To begin with just knowing a project has build target X doesn't really tell you how to build X, just that you can. You need to feed that selection back into the project-type or export it directly as is. I recently added a feature to list build artifacts (for debugger integration) and that shows just how much variety there is here. Lastly, just a general point (sorry for writing so much), I think any feature for this shouldn't assume only a single project type is valid. There should be a concept of a primary type just to make commands like configure or build make sense relative to each other, but nothing stops a project from matching two types at once and at least IME that's the more natural state of things. I commonly work on C++ projects but we also have a package.json in those projects file so we can depend on prettier and other non-C++ specific linters. The way projection gets around this is by always matching all defined project types. Users can add to the list of matched types for the current project and can cycle the primary project type. Certain interfaces that aren't single project specific like the aforementioned projection-multi-compile will source compilation targets from all applicable project types. This provides an extremely rich interface for interacting with projects (at least IMO). Let me know if anyone has any thoughts or questions about projection. I'm not averse to re-aligning across something in Emacs mainline. The only minor concern is how specific it is to the kinds of projects I work on and that may not generalise well to others. -- Mohsin Kaleem