* Project out of sources compilation [not found] <4wwljrdnra3bsloehioa46y24ozxajajmvf2elvskxxq3mhtg2.ref@pyv2z5snot6h> @ 2024-03-16 13:12 ` Ergus 2024-03-16 16:50 ` Konstantin Kharlamov ` (2 more replies) 0 siblings, 3 replies; 57+ messages in thread From: Ergus @ 2024-03-16 13:12 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel Hi: These days I have been working with cmake projects here and there and in spite of I could handle most of the work from emacs, it required a lot of extra time to make it more or less comfortable. I wrote a couple of simple functions to manage my needs, but at the end I think that there are some small piece missing to handle common workflows and glue everything (with the users in mind of course): 1. Out of sources compilation. Most of projects now prefer to do out-of sources compilation. Either to keep source code clean or to keep multiple compilations at the same time (i.e Debug/Release/win32) The project.el package has already some compilation commands, but they assume that the compilation will be executed in the project's root... which is not true most of the time. Maybe we may add an extra custom variable that could be specified in the dir-locals.el in order specify where the compilation command must be executed. Some more heuristics here is possible, but I would settle for at least something simpler. 2. Eglot compilations database place. When compilation is out of sources the cmake generated compile_commands.json also goes in that directory by default. This issue can be managed with a line in dir-locals, or just manually coping the database. ((eglot-workspace-configuration . (:clangd (:initializationOptions (:compilationDatabasePath "build"))))) Probably some simple slight integration of Eglot with Project may help. 2.1 This mixes with the previous one because if we change the compilation directory the line with initializationOptions is not updated and requires manual intervention 3. Projects multiple backends This one is tricky because at the moment I have gtags-mode, that includes a backend for project.el, there is the default backend, but also we could add something called cmake-backend (i.e looks for CMakeLists.txt that includes a 'project' entry) In that case emacs cannot use all the information form the three even if it is not contradictory, so the user ends up opening the terminal and doing things manually. 4. Flymake integration Even without eglot, flymake should be capable to work very easily with cmake projects. This step is also a stage before doing a proper plugin integration of tools like cppcheck for flymake. 5. Project local variables (a man can dream, a man can dream) There are some situations where we want to have variables shared among a project. (i.e some output directory, logging option when executing, flags, environment variables). At the moment these options work partially by using directory variables. If we have the concept of a "project", maybe it is logical to have some sort of project scope concept, specially for projects sharing a common root. For example vs-code adds a subdirectory with project variables that the user (but also any plugin) can refer to in the project's scope. -- I could try to implement some of this with your help; but I need some feedback on which of them are desired and which are not. Or which ones are maybe better to put as feature requests for a more skilled lisper or package maintainer. WDYT? Ergus ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-16 13:12 ` Project out of sources compilation Ergus @ 2024-03-16 16:50 ` Konstantin Kharlamov 2024-03-16 19:00 ` Ergus 2024-03-17 2:53 ` Dmitry Gutov 2024-03-17 11:36 ` Augusto Stoffel 2 siblings, 1 reply; 57+ messages in thread From: Konstantin Kharlamov @ 2024-03-16 16:50 UTC (permalink / raw) To: Ergus, Dmitry Gutov; +Cc: emacs-devel On Sat, 2024-03-16 at 14:12 +0100, Ergus wrote: > 2. Eglot compilations database place. > > When compilation is out of sources the cmake generated > compile_commands.json also goes in that directory by default. > > This issue can be managed with a line in dir-locals, or just manually > coping the database. > > ((eglot-workspace-configuration > . (:clangd (:initializationOptions > (:compilationDatabasePath > "build"))))) Just wanted to clarify two things: 1. You can't just copy clangd database (i.e. `compile_commands.json`) because the field "directory" has absolute path and clangd doesn't support relative one. So you'll also have to regexp-replace the paths after it's been copied. 2. If your out-of-source dir is called `build/`, then you don't need to configure clangd to support it, because it handles that special case. > Probably some simple slight integration of Eglot with Project may > help. > > 2.1 This mixes with the previous one because if we change the > compilation directory the line with initializationOptions is not > updated and requires manual intervention Some generic support for pointing out the compilation dir sounds indeed useful if it's possible. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-16 16:50 ` Konstantin Kharlamov @ 2024-03-16 19:00 ` Ergus 2024-03-16 20:56 ` Konstantin Kharlamov 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-03-16 19:00 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: Dmitry Gutov, emacs-devel Hi: On Sat, Mar 16, 2024 at 07:50:49PM +0300, Konstantin Kharlamov wrote: >On Sat, 2024-03-16 at 14:12 +0100, Ergus wrote: >> 2. Eglot compilations database place. >> >> When compilation is out of sources the cmake generated >> compile_commands.json also goes in that directory by default. >> >> This issue can be managed with a line in dir-locals, or just manually >> coping the database. >> >> ((eglot-workspace-configuration >> � . (:clangd (:initializationOptions >> (:compilationDatabasePath >> � "build"))))) > >Just wanted to clarify two things: > >1. You can't just copy clangd database (i.e. `compile_commands.json`) >because the field "directory" has absolute path and clangd doesn't >support relative one. So you'll also have to regexp-replace the paths >after it's been copied. Yes, I know that (now). But that is actually the most popular solution in: https://emacs.stackexchange.com/questions/73922/how-do-you-tell-eglot-and-clangd-about-the-compilation-database-compile-command >2. If your out-of-source dir is called `build/`, then you don't need to >configure clangd to support it, because it handles that special case. > Good to know, I didn't know because I always use names like build_debug, build_x64, build_clang and so on. >> Probably some simple slight integration of Eglot with Project may >> help. >> >> �� 2.1 This mixes with the previous one because if we change the >> �� compilation directory the line with initializationOptions is not >> �� updated and requires manual intervention > >Some generic support for pointing out the compilation dir sounds indeed >useful if it's possible. > Lets wait for Dmitry's suggestion. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-16 19:00 ` Ergus @ 2024-03-16 20:56 ` Konstantin Kharlamov 0 siblings, 0 replies; 57+ messages in thread From: Konstantin Kharlamov @ 2024-03-16 20:56 UTC (permalink / raw) To: Ergus; +Cc: Dmitry Gutov, emacs-devel On Sat, 2024-03-16 at 20:00 +0100, Ergus wrote: > Hi: > > On Sat, Mar 16, 2024 at 07:50:49PM +0300, Konstantin Kharlamov wrote: > > On Sat, 2024-03-16 at 14:12 +0100, Ergus wrote: > > > 2. Eglot compilations database place. > > > > > > When compilation is out of sources the cmake generated > > > compile_commands.json also goes in that directory by default. > > > > > > This issue can be managed with a line in dir-locals, or just > > > manually > > > coping the database. > > > > > > ((eglot-workspace-configuration > > > � . (:clangd (:initializationOptions > > > (:compilationDatabasePath > > > � "build"))))) > > > > Just wanted to clarify two things: > > > > 1. You can't just copy clangd database (i.e. > > `compile_commands.json`) > > because the field "directory" has absolute path and clangd doesn't > > support relative one. So you'll also have to regexp-replace the > > paths > > after it's been copied. > > Yes, I know that (now). But that is actually the most popular > solution in: > > https://emacs.stackexchange.com/questions/73922/how-do-you-tell-eglot-and-clangd-about-the-compilation-database-compile-command Actually, I stand corrected. I certainly remember that way not working ≈2 years ago (last time I tried and learned all that information); however right now creating a symlink to `compile_commands.json` as well as just copying does work. I just tested that on a C project at work by symlinking/copying the json file, then starting lsp and trying to "goto definition" to a generated `.h` file that resides in the build dir. It works. I tested that both with dir called `build` and `build-docs` (in the latter case `build` dir was absent to make sure). clangd version 16.0.6 ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-16 13:12 ` Project out of sources compilation Ergus 2024-03-16 16:50 ` Konstantin Kharlamov @ 2024-03-17 2:53 ` Dmitry Gutov 2024-03-17 7:22 ` Ergus 2024-03-17 11:36 ` Augusto Stoffel 2 siblings, 1 reply; 57+ messages in thread From: Dmitry Gutov @ 2024-03-17 2:53 UTC (permalink / raw) To: Ergus; +Cc: emacs-devel Hi! On 16/03/2024 15:12, Ergus wrote: > These days I have been working with cmake projects here and there and in > spite of I could handle most of the work from emacs, it required a lot > of extra time to make it more or less comfortable. > > I wrote a couple of simple functions to manage my needs, but at the end > I think that there are some small piece missing to handle common > workflows and glue everything (with the users in mind of course): > > 1. Out of sources compilation. > > Most of projects now prefer to do out-of sources compilation. Either to > keep source code clean or to keep multiple compilations at the same time > (i.e Debug/Release/win32) > > The project.el package has already some compilation commands, but they > assume that the compilation will be executed in the project's > root... which is not true most of the time. > > Maybe we may add an extra custom variable that could be specified in the > dir-locals.el in order specify where the compilation command must be > executed. > > Some more heuristics here is possible, but I would settle for at least > something simpler. project.el has just one, very simple command, where the only thing that it does it switch to the root first. How will you customize it? With a hook, where the user would write a function "determine a directory for compilation"? They might as well define a new command - or redefine this one. Or just an option with relative directory name? > 2. Eglot compilations database place. > > When compilation is out of sources the cmake generated > compile_commands.json also goes in that directory by default. > > This issue can be managed with a line in dir-locals, or just manually > coping the database. > > ((eglot-workspace-configuration > . (:clangd (:initializationOptions (:compilationDatabasePath > "build"))))) > > Probably some simple slight integration of Eglot with Project may help. That seems like it can be a Eglot user option. Again, just storing a file name relative to the project root? > 2.1 This mixes with the previous one because if we change the > compilation directory the line with initializationOptions is not > updated and requires manual intervention > > 3. Projects multiple backends > > This one is tricky because at the moment I have gtags-mode, that > includes a backend for project.el, there is the default backend, but > also we could add something called cmake-backend (i.e looks for > CMakeLists.txt that includes a 'project' entry) > > In that case emacs cannot use all the information form the three even if > it is not contradictory, so the user ends up opening the terminal and > doing things manually. Indeed, project.el doesn't "merge" backends. Is there an obvious algorithm for merging backends which would be understandable to an average user? If the only thing you wanted combined is the root detection, I suggest reusing the variable project-vc-extra-root-markers, automatically or manually (just have the user set it). If its data structure is now powerful enough, it can be updated. For example, if the logic both looks for CMakeLists.txt and checks its contents, project-vc-extra-root-markers could support cons entries like (MARKER . CHECK-FN). > 4. Flymake integration > > Even without eglot, flymake should be capable to work very easily with > cmake projects. > > This step is also a stage before doing a proper plugin integration of > tools like cppcheck for flymake. Is there something particular that is required? > 5. Project local variables (a man can dream, a man can dream) > > There are some situations where we want to have variables shared among a > project. (i.e some output directory, logging option when executing, > flags, environment variables). > > At the moment these options work partially by using directory > variables. If we have the concept of a "project", maybe it is logical to > have some sort of project scope concept, specially for projects sharing > a common root. > > For example vs-code adds a subdirectory with project variables that the > user (but also any plugin) can refer to in the project's scope. Does such subdirectory in VS Code affect the project residing its its parent directory, or some other projects as well? Your description above sounds more like our .dir-locals.el. And the directory locals facility in Emacs also has the less well-known capability called "directory class", see the bottom of https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html. I think it should work okay for sharing variables between projects. Perhaps it's less user-friendly than one had hoped, I don't know. Some improvements for related UIs would be welcome. Just creating a parallel built-in way to set variables inside directories but for projects sounds a bit much. Also, we don't always detect a buffer's project before the user asks for it. So I'm not sure what hooks could be added, even if we wanted. > I could try to implement some of this with your help; but I need some > feedback on which of them are desired and which are not. Or which ones > are maybe better to put as feature requests for a more skilled lisper or > package maintainer. Patches are welcome, but see above. Cheers, Dmitry. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 2:53 ` Dmitry Gutov @ 2024-03-17 7:22 ` Ergus 2024-03-17 8:45 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-03-17 7:22 UTC (permalink / raw) To: emacs-devel, Dmitry Gutov Hi: On March 17, 2024 3:53:42 AM GMT+01:00, Dmitry Gutov <dmitry@gutov.dev> wrote: >Hi! > >On 16/03/2024 15:12, Ergus wrote: > >> These days I have been working with cmake projects here and there and in >> spite of I could handle most of the work from emacs, it required a lot >> of extra time to make it more or less comfortable. >> >> I wrote a couple of simple functions to manage my needs, but at the end >> I think that there are some small piece missing to handle common >> workflows and glue everything (with the users in mind of course): >> >> 1. Out of sources compilation. >> >> Most of projects now prefer to do out-of sources compilation. Either to >> keep source code clean or to keep multiple compilations at the same time >> (i.e Debug/Release/win32) >> >> The project.el package has already some compilation commands, but they >> assume that the compilation will be executed in the project's >> root... which is not true most of the time. >> >> Maybe we may add an extra custom variable that could be specified in the >> dir-locals.el in order specify where the compilation command must be >> executed. >> >> Some more heuristics here is possible, but I would settle for at least >> something simpler. > >project.el has just one, very simple command, where the only thing that it does it switch to the root first. How will you customize it? With a hook, where the user would write a function "determine a directory for compilation"? They might as well define a new command - or redefine this one. Or just an option with relative directory name? > IMO the only thing we need is probably a variable/custom like project-build-dir. The user can define it in the dir-locals and the project command will use it if defined/ else use project-root. Maybe the backend could initialize it. Alternatively (and not totally exclusive) project.el could define a project-build-dir function that project backends could optionally redefine (i.e I use a plist as project id in gags-mode and getting any stored property from there is very easy with a command). By default it will be an alias for project-root in the VC backend. There is also some need for a 'bin' dir, that is, where the final executable will reside, useful to execute and debug with tools like gud and independent from 'build'... For example in a python project this may be the project root OR where the file with __main__ resides, but a python project usually won't specify a build dir. But let's go for one thing at a time. >> 2. Eglot compilations database place. >> >> When compilation is out of sources the cmake generated >> compile_commands.json also goes in that directory by default. >> >> This issue can be managed with a line in dir-locals, or just manually >> coping the database. >> >> ((eglot-workspace-configuration >> . (:clangd (:initializationOptions (:compilationDatabasePath >> "build"))))) >> >> Probably some simple slight integration of Eglot with Project may help. > >That seems like it can be a Eglot user option. Again, just storing a file name relative to the project root? > Actually it doesn't need to be relative. For example QtCreator creates the build dir outside the sources directory in the same level. So, the only requirement is to be a valid path. Relative to root or absolute one >> 2.1 This mixes with the previous one because if we change the >> compilation directory the line with initializationOptions is not >> updated and requires manual intervention >> >> 3. Projects multiple backends >> >> This one is tricky because at the moment I have gtags-mode, that >> includes a backend for project.el, there is the default backend, but >> also we could add something called cmake-backend (i.e looks for >> CMakeLists.txt that includes a 'project' entry) >> >> In that case emacs cannot use all the information form the three even if >> it is not contradictory, so the user ends up opening the terminal and >> doing things manually. > >Indeed, project.el doesn't "merge" backends. Is there an obvious algorithm for merging backends which would be understandable to an average user? > >If the only thing you wanted combined is the root detection, I suggest reusing the variable project-vc-extra-root-markers, automatically or manually (just have the user set it). If its data structure is now powerful enough, it can be updated. For example, if the logic both looks for CMakeLists.txt and checks its contents, project-vc-extra-root-markers could support cons entries like (MARKER . CHECK-FN). Actually the idea is as simple as: if any of the backends explicitly specifies some property that the others don't, then use that one. Applied in this case. VC backend does not have any "build" Information in general. But a cmake backend could detect a "build" directory and propose it (looking for a CMake cache inside it for example). An hipothetical autotools backend may do the same. > >> 4. Flymake integration >> >> Even without eglot, flymake should be capable to work very easily with >> cmake projects. >> >> This step is also a stage before doing a proper plugin integration of >> tools like cppcheck for flymake. > >Is there something particular that is required? > >> 5. Project local variables (a man can dream, a man can dream) >> >> There are some situations where we want to have variables shared among a >> project. (i.e some output directory, logging option when executing, >> flags, environment variables). >> >> At the moment these options work partially by using directory >> variables. If we have the concept of a "project", maybe it is logical to >> have some sort of project scope concept, specially for projects sharing >> a common root. >> >> For example vs-code adds a subdirectory with project variables that the >> user (but also any plugin) can refer to in the project's scope. > >Does such subdirectory in VS Code affect the project residing its its parent directory, or some other projects as well? Your description above sounds more like our .dir-locals.el. > >And the directory locals facility in Emacs also has the less well-known capability called "directory class", see the bottom of https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html. I think it should work okay for sharing variables between projects. > >Perhaps it's less user-friendly than one had hoped, I don't know. Some improvements for related UIs would be welcome. > >Just creating a parallel built-in way to set variables inside directories but for projects sounds a bit much. Also, we don't always detect a buffer's project before the user asks for it. So I'm not sure what hooks could be added, even if we wanted. > Ok, I buy this one because there are the dir-locals, which are not ideal for project purposes, but it is already there and it isn't worth adding another abstraction layer >> I could try to implement some of this with your help; but I need some >> feedback on which of them are desired and which are not. Or which ones >> are maybe better to put as feature requests for a more skilled lisper or >> package maintainer. > >Patches are welcome, but see above. > >Cheers, >Dmitry. > Best, Ergus -- Sent from my Android device with K-9 Mail. Please excuse my brevity. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 7:22 ` Ergus @ 2024-03-17 8:45 ` Eli Zaretskii 2024-03-17 17:33 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-03-17 8:45 UTC (permalink / raw) To: Ergus, dmitry; +Cc: emacs-devel > Date: Sun, 17 Mar 2024 08:22:56 +0100 > From: Ergus <spacibba@aol.com> > > >> 1. Out of sources compilation. > >> > >> Most of projects now prefer to do out-of sources compilation. Either to > >> keep source code clean or to keep multiple compilations at the same time > >> (i.e Debug/Release/win32) > >> > >> The project.el package has already some compilation commands, but they > >> assume that the compilation will be executed in the project's > >> root... which is not true most of the time. > >> > >> Maybe we may add an extra custom variable that could be specified in the > >> dir-locals.el in order specify where the compilation command must be > >> executed. > >> > >> Some more heuristics here is possible, but I would settle for at least > >> something simpler. > > > >project.el has just one, very simple command, where the only thing that it does it switch to the root first. How will you customize it? With a hook, where the user would write a function "determine a directory for compilation"? They might as well define a new command - or redefine this one. Or just an option with relative directory name? > > > > IMO the only thing we need is probably a variable/custom like project-build-dir. The user can define it in the dir-locals and the project command will use it if defined/ else use project-root. Maybe the backend could initialize it. > > Alternatively (and not totally exclusive) project.el could define a project-build-dir function that project backends could optionally redefine (i.e I use a plist as project id in gags-mode and getting any stored property from there is very easy with a command). By default it will be an alias for project-root in the VC backend. Maybe I'm missing something, but isn't the build tree just one more tree that is part of the project? If so, can't you use project-external-roots to add this tree to the project? I thought this was the mechanism to add trees to a project as included in the original design of project.el and its support in Emacs? > There is also some need for a 'bin' dir, that is, where the final executable will reside, useful to execute and debug with tools like gud and independent from 'build'... For example in a python project this may be the project root OR where the file with __main__ resides, but a python project usually won't specify a build dir. But let's go for one thing at a time. Likewise here. Or what am I missing? ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 8:45 ` Eli Zaretskii @ 2024-03-17 17:33 ` Ergus 2024-03-17 17:38 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-03-17 17:33 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dmitry, emacs-devel On Sun, Mar 17, 2024 at 10:45:29AM +0200, Eli Zaretskii wrote: >> Date: Sun, 17 Mar 2024 08:22:56 +0100 >> From: Ergus <spacibba@aol.com> >> >> > >> >project.el has just one, very simple command, where the only thing that it does it switch to the root first. How will you customize it? With a hook, where the user would write a function "determine a directory for compilation"? They might as well define a new command - or redefine this one. Or just an option with relative directory name? >> > >> >> IMO the only thing we need is probably a variable/custom like project-build-dir. The user can define it in the dir-locals and the project command will use it if defined/ else use project-root. Maybe the backend could initialize it. >> >> Alternatively (and not totally exclusive) project.el could define a project-build-dir function that project backends could optionally redefine (i.e I use a plist as project id in gags-mode and getting any stored property from there is very easy with a command). By default it will be an alias for project-root in the VC backend. > >Maybe I'm missing something, but isn't the build tree just one more >tree that is part of the project? If so, can't you use >project-external-roots to add this tree to the project? I thought >this was the mechanism to add trees to a project as included in the >original design of project.el and its support in Emacs? > >> There is also some need for a 'bin' dir, that is, where the final executable will reside, useful to execute and debug with tools like gud and independent from 'build'... For example in a python project this may be the project root OR where the file with __main__ resides, but a python project usually won't specify a build dir. But let's go for one thing at a time. > >Likewise here. > >Or what am I missing? Hi Eli: More or less we have it, that's why I said that there was just some (small) missing pieces. We have the `project-external-roots`, but project.el uses them only to find files and regexps. So it looks like they are intended to be source places somehow. The compile or debug programs doesn't know that they are intended to execute there. However, a `build` or `bin` are different because they are where the `compile` or `gud` are intended to run; generally not a place to search for sources (unless the source is generated like config.h). Two examples: ``` git clone emacs cd emacs mkdir build # or mybuild, build_debug.. any name ./autogen.sh # (this is intendedto happen in the root) cd build ../configure options // This creates a Makefile make make install ``` On cmake ``` git clone project cd project // Creates a CMakeCache.txt Alternative 1 cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=true -DCMAKE_BUILD_TYPE=Debug -B build/ cd build Alternative 2 mkdir build cd build cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=true -DCMAKE_BUILD_TYPE=Debug .. make make install ``` The pattern is pretty much the same, so it is pretty simple to allow projects.el to simplify the generation-compilation-execution-debug workflow. And with autotools+cmake we are probably covering a huge range of projects around. Best, Ergus ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 17:33 ` Ergus @ 2024-03-17 17:38 ` Eli Zaretskii 2024-03-17 17:58 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-03-17 17:38 UTC (permalink / raw) To: Ergus; +Cc: dmitry, emacs-devel > Date: Sun, 17 Mar 2024 18:33:21 +0100 > From: Ergus <spacibba@aol.com> > Cc: dmitry@gutov.dev, emacs-devel@gnu.org > > >Maybe I'm missing something, but isn't the build tree just one more > >tree that is part of the project? If so, can't you use > >project-external-roots to add this tree to the project? I thought > >this was the mechanism to add trees to a project as included in the > >original design of project.el and its support in Emacs? > > > > >> There is also some need for a 'bin' dir, that is, where the final executable will reside, useful to execute and debug with tools like gud and independent from 'build'... For example in a python project this may be the project root OR where the file with __main__ resides, but a python project usually won't specify a build dir. But let's go for one thing at a time. > > > >Likewise here. > > > >Or what am I missing? > > Hi Eli: > > More or less we have it, that's why I said that there was just some > (small) missing pieces. > > We have the `project-external-roots`, but project.el uses them only to > find files and regexps. So it looks like they are intended to be source > places somehow. > > The compile or debug programs doesn't know that they are intended to > execute there. > > However, a `build` or `bin` are different because they are where the > `compile` or `gud` are intended to run; generally not a place to search > for sources (unless the source is generated like config.h). Are you saying that "M-x compile" and "M-x gdb" are not (yet) supported by project.el? ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 17:38 ` Eli Zaretskii @ 2024-03-17 17:58 ` Ergus 0 siblings, 0 replies; 57+ messages in thread From: Ergus @ 2024-03-17 17:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dmitry, emacs-devel On Sun, Mar 17, 2024 at 07:38:16PM +0200, Eli Zaretskii wrote: >> Date: Sun, 17 Mar 2024 18:33:21 +0100 >> From: Ergus <spacibba@aol.com> >> Cc: dmitry@gutov.dev, emacs-devel@gnu.org >> >> >Maybe I'm missing something, but isn't the build tree just one more >> >tree that is part of the project? If so, can't you use >> >project-external-roots to add this tree to the project? I thought >> >this was the mechanism to add trees to a project as included in the >> >original design of project.el and its support in Emacs? >> > >> >> >> There is also some need for a 'bin' dir, that is, where the final executable will reside, useful to execute and debug with tools like gud and independent from 'build'... For example in a python project this may be the project root OR where the file with __main__ resides, but a python project usually won't specify a build dir. But let's go for one thing at a time. >> > >> >Likewise here. >> > >> >Or what am I missing? >> >> Hi Eli: >> >> More or less we have it, that's why I said that there was just some >> (small) missing pieces. >> >> We have the `project-external-roots`, but project.el uses them only to >> find files and regexps. So it looks like they are intended to be source >> places somehow. >> >> The compile or debug programs doesn't know that they are intended to >> execute there. >> >> However, a `build` or `bin` are different because they are where the >> `compile` or `gud` are intended to run; generally not a place to search >> for sources (unless the source is generated like config.h). > >Are you saying that "M-x compile" and "M-x gdb" are not (yet) >supported by project.el? > Kind of. There is project-compile, but executes in the root directory. And M-x compile does not have any custom to control the execution place, so it needs to do a let around it. something similar happen to gdb, or project-eshell. So, what is not actually supported is out of sources compilation/execution. In the first email I explained that part. Even Eglot requires extra work to function properly. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-16 13:12 ` Project out of sources compilation Ergus 2024-03-16 16:50 ` Konstantin Kharlamov 2024-03-17 2:53 ` Dmitry Gutov @ 2024-03-17 11:36 ` Augusto Stoffel 2024-03-17 17:47 ` Ergus 2 siblings, 1 reply; 57+ messages in thread From: Augusto Stoffel @ 2024-03-17 11:36 UTC (permalink / raw) To: Ergus; +Cc: Dmitry Gutov, emacs-devel On Sat, 16 Mar 2024 at 14:12, Ergus wrote: > 5. Project local variables (a man can dream, a man can dream) > > There are some situations where we want to have variables shared among a > project. (i.e some output directory, logging option when executing, > flags, environment variables). > > At the moment these options work partially by using directory > variables. If we have the concept of a "project", maybe it is logical to > have some sort of project scope concept, specially for projects sharing > a common root. For Emacs variables, why you think dir-local variables only works “partially”? As to environment variables, they are generally assumed to be global in Emacs and it goes a bit against the grain to make them buffer-local / project dependent. Nonetheless, there are packages for that (one is buffer-env, which I wrote) and they work fine (at least for me). > For example vs-code adds a subdirectory with project variables that the > user (but also any plugin) can refer to in the project's scope. Is this meant to store editor configuration or environment variables? I guess turning VSCode configuration variables into Emacs alternatives would be tricky. But if this is about env vars and the directory organization is sensible, then one could configure buffer-env to interoperate. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 11:36 ` Augusto Stoffel @ 2024-03-17 17:47 ` Ergus 2024-03-19 18:36 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-03-17 17:47 UTC (permalink / raw) To: Augusto Stoffel; +Cc: Dmitry Gutov, emacs-devel On Sun, Mar 17, 2024 at 12:36:44PM +0100, Augusto Stoffel wrote: >On Sat, 16 Mar 2024 at 14:12, Ergus wrote: > >> 5. Project local variables (a man can dream, a man can dream) >> >> There are some situations where we want to have variables shared among a >> project. (i.e some output directory, logging option when executing, >> flags, environment variables). >> >> At the moment these options work partially by using directory >> variables. If we have the concept of a "project", maybe it is logical to >> have some sort of project scope concept, specially for projects sharing >> a common root. > >For Emacs variables, why you think dir-local variables only works >“partially”? > >As to environment variables, they are generally assumed to be global in >Emacs and it goes a bit against the grain to make them buffer-local / >project dependent. Nonetheless, there are packages for that (one is >buffer-env, which I wrote) and they work fine (at least for me). > They work for one directory, but when the project includes multiple roots (project-external-roots) the variables are somehow missing just when jumping with xref to a definition. However, we can ignore this as I mentioned before. >> For example vs-code adds a subdirectory with project variables that the >> user (but also any plugin) can refer to in the project's scope. > >Is this meant to store editor configuration or environment variables? I >guess turning VSCode configuration variables into Emacs alternatives >would be tricky. No please. No interaction-importing from other editors will be maintainable in the long path. > But if this is about env vars and the directory >organization is sensible, then one could configure buffer-env to >interoperate. This is it. The idea is to extend project.el in order to bring more project-oriented features. Lets say: The user (or project.el backend) could specify the `build` directory and the environment that needs to be set to execute the program from the build or bin directory. So with a simple modification of dir-locals.el the user may be capable to run M-x compile (or project-compile), M-x gud-gdb... or being more ambitious M-x project-generate (to call autogen.sh and ./configure or cmake depending of the project-backend) For sure we wont cover the 100% of the projects, but wuth automake and autotools we will be very close (and in the future someone could add other backends for it) ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: Project out of sources compilation 2024-03-17 17:47 ` Ergus @ 2024-03-19 18:36 ` Ergus 2024-03-27 16:38 ` [PATCH] " Ergus 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-03-19 18:36 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 2725 bytes --] Hi Dmitry: Here I attach a very simple approach to add support for out of sources compilation in project.el This is just a POC, but to have some starting point to discuss. Best, Ergus On Sun, Mar 17, 2024 at 06:47:43PM +0100, Ergus wrote: >On Sun, Mar 17, 2024 at 12:36:44PM +0100, Augusto Stoffel wrote: >>On Sat, 16 Mar 2024 at 14:12, Ergus wrote: >> >>>5. Project local variables (a man can dream, a man can dream) >>> >>>There are some situations where we want to have variables shared among a >>>project. (i.e some output directory, logging option when executing, >>>flags, environment variables). >>> >>>At the moment these options work partially by using directory >>>variables. If we have the concept of a "project", maybe it is logical to >>>have some sort of project scope concept, specially for projects sharing >>>a common root. >> >>For Emacs variables, why you think dir-local variables only works >>“partially”? >> >>As to environment variables, they are generally assumed to be global in >>Emacs and it goes a bit against the grain to make them buffer-local / >>project dependent. Nonetheless, there are packages for that (one is >>buffer-env, which I wrote) and they work fine (at least for me). >> >They work for one directory, but when the project includes multiple >roots (project-external-roots) the variables are somehow missing just >when jumping with xref to a definition. > >However, we can ignore this as I mentioned before. > >>>For example vs-code adds a subdirectory with project variables that the >>>user (but also any plugin) can refer to in the project's scope. >> >>Is this meant to store editor configuration or environment variables? I >>guess turning VSCode configuration variables into Emacs alternatives >>would be tricky. > >No please. No interaction-importing from other editors will be >maintainable in the long path. > >>But if this is about env vars and the directory >>organization is sensible, then one could configure buffer-env to >>interoperate. > >This is it. The idea is to extend project.el in order to bring more >project-oriented features. > >Lets say: > >The user (or project.el backend) could specify the `build` directory and >the environment that needs to be set to execute the program from the >build or bin directory. > >So with a simple modification of dir-locals.el the user may be capable >to run M-x compile (or project-compile), M-x gud-gdb... or being more >ambitious M-x project-generate (to call autogen.sh and ./configure or >cmake depending of the project-backend) > >For sure we wont cover the 100% of the projects, but wuth automake and >autotools we will be very close (and in the future someone could add >other backends for it) > > > > > [-- Attachment #2: project-build-dir.patch --] [-- Type: text/plain, Size: 2875 bytes --] commit cfa10dfeac01ae25a7acd6857fae0b377b625779 Author: Jimmy Aguilar Mena <kratsbinovish@gmail.com> Date: Tue Mar 19 17:57:25 2024 +0100 Add basic project-build-dir implementation This is just a dummy prototype to discuss about alternatives. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index ac18aceadcf..0ca4ca85566 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -51,6 +51,9 @@ ;; files inside the root must not be considered a part of it). It ;; should be consistent with `project-files'. ;; +;; `project-build-dir' can be overridden if the project backend has some +;; extra information about the project build directory. +;; ;; This list can change in future versions. ;; ;; Transient project: @@ -208,6 +211,12 @@ project-prompter :group 'project :version "30.1") +(defcustom project-build-dir nil + "Build directory for current project." + :type 'directory + :safe t + :version "30.1") + ;;;###autoload (defun project-current (&optional maybe-prompt directory) "Return the project instance in DIRECTORY, defaulting to `default-directory'. @@ -289,8 +298,30 @@ project-external-roots headers search path, load path, class path, and so on." nil) +(cl-defgeneric project-build-dir (_project) + "Return build directory of the current PROJECT. + +This function is intended to be defined by the backend when possible. +Otherwise this returns nil and the `project-compile' command will be +called in the project-root. +If the user defines the directory-local variable `project-build-dir' it +will have precedence over the result of this function." + nil) + +(defun project-get-build-dir (project) + "Return build directory of the current PROJECT. +If the variable `project-build-dir' is defined, this function returns +it, otherwise it returns the project root. If the defined path is +relative, this expands it relatively to the project's root" + (let ((dir (or project-build-dir + (project-build-dir project) + (project-root project)))) ;; I assume project-root is absolute + (if (file-name-absolute-p dir) + dir + (expand-file-name dir (project-root project))))) + (cl-defgeneric project-name (project) - "A human-readable name for the project. + "A human-readable name for the PROJECT. Nominally unique, but not enforced." (file-name-nondirectory (directory-file-name (project-root project)))) @@ -1391,7 +1422,7 @@ project-compile "Run `compile' in the project root." (declare (interactive-only compile)) (interactive) - (let ((default-directory (project-root (project-current t))) + (let ((default-directory (project-get-build-dir (project-current t))) (compilation-buffer-name-function (or project-compilation-buffer-name-function compilation-buffer-name-function))) ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH] Project out of sources compilation 2024-03-19 18:36 ` Ergus @ 2024-03-27 16:38 ` Ergus 2024-03-31 2:41 ` Dmitry Gutov 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-03-27 16:38 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 6361 bytes --] Hi: Here I attach a very simple patch to allow project out of sources compilation and project build detection. So far I already implemented a very primitive backend [1] for project.el using these features to detect and compile autotools and cmake projects; and, at some point I will propose it for elpa. But I need to work a bit more on it; and, of course, the functionalities in the attached patch need to go to vanilla this way or some other equivalent. Best, Ergus [1] https://github.com/Ergus/project-multi-mode/blob/master/project-multi-mode.el On Tue, Mar 19, 2024 at 07:36:35PM +0100, Ergus wrote: >Hi Dmitry: > >Here I attach a very simple approach to add support for out of sources >compilation in project.el > >This is just a POC, but to have some starting point to discuss. > >Best, >Ergus > > > >On Sun, Mar 17, 2024 at 06:47:43PM +0100, Ergus wrote: >>On Sun, Mar 17, 2024 at 12:36:44PM +0100, Augusto Stoffel wrote: >>>On Sat, 16 Mar 2024 at 14:12, Ergus wrote: >>> >>>>5. Project local variables (a man can dream, a man can dream) >>>> >>>>There are some situations where we want to have variables shared among a >>>>project. (i.e some output directory, logging option when executing, >>>>flags, environment variables). >>>> >>>>At the moment these options work partially by using directory >>>>variables. If we have the concept of a "project", maybe it is logical to >>>>have some sort of project scope concept, specially for projects sharing >>>>a common root. >>> >>>For Emacs variables, why you think dir-local variables only works >>>“partially”? >>> >>>As to environment variables, they are generally assumed to be global in >>>Emacs and it goes a bit against the grain to make them buffer-local / >>>project dependent. Nonetheless, there are packages for that (one is >>>buffer-env, which I wrote) and they work fine (at least for me). >>> >>They work for one directory, but when the project includes multiple >>roots (project-external-roots) the variables are somehow missing just >>when jumping with xref to a definition. >> >>However, we can ignore this as I mentioned before. >> >>>>For example vs-code adds a subdirectory with project variables that the >>>>user (but also any plugin) can refer to in the project's scope. >>> >>>Is this meant to store editor configuration or environment variables? I >>>guess turning VSCode configuration variables into Emacs alternatives >>>would be tricky. >> >>No please. No interaction-importing from other editors will be >>maintainable in the long path. >> >>>But if this is about env vars and the directory >>>organization is sensible, then one could configure buffer-env to >>>interoperate. >> >>This is it. The idea is to extend project.el in order to bring more >>project-oriented features. >> >>Lets say: >> >>The user (or project.el backend) could specify the `build` directory and >>the environment that needs to be set to execute the program from the >>build or bin directory. >> >>So with a simple modification of dir-locals.el the user may be capable >>to run M-x compile (or project-compile), M-x gud-gdb... or being more >>ambitious M-x project-generate (to call autogen.sh and ./configure or >>cmake depending of the project-backend) >> >>For sure we wont cover the 100% of the projects, but wuth automake and >>autotools we will be very close (and in the future someone could add >>other backends for it) >> >> >> >> >> >commit cfa10dfeac01ae25a7acd6857fae0b377b625779 >Author: Jimmy Aguilar Mena <kratsbinovish@gmail.com> >Date: Tue Mar 19 17:57:25 2024 +0100 > > Add basic project-build-dir implementation > > This is just a dummy prototype to discuss about alternatives. > >diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el >index ac18aceadcf..0ca4ca85566 100644 >--- a/lisp/progmodes/project.el >+++ b/lisp/progmodes/project.el >@@ -51,6 +51,9 @@ > ;; files inside the root must not be considered a part of it). It > ;; should be consistent with `project-files'. > ;; >+;; `project-build-dir' can be overridden if the project backend has some >+;; extra information about the project build directory. >+;; > ;; This list can change in future versions. > ;; > ;; Transient project: >@@ -208,6 +211,12 @@ project-prompter > :group 'project > :version "30.1") > >+(defcustom project-build-dir nil >+ "Build directory for current project." >+ :type 'directory >+ :safe t >+ :version "30.1") >+ > ;;;###autoload > (defun project-current (&optional maybe-prompt directory) > "Return the project instance in DIRECTORY, defaulting to `default-directory'. >@@ -289,8 +298,30 @@ project-external-roots > headers search path, load path, class path, and so on." > nil) > >+(cl-defgeneric project-build-dir (_project) >+ "Return build directory of the current PROJECT. >+ >+This function is intended to be defined by the backend when possible. >+Otherwise this returns nil and the `project-compile' command will be >+called in the project-root. >+If the user defines the directory-local variable `project-build-dir' it >+will have precedence over the result of this function." >+ nil) >+ >+(defun project-get-build-dir (project) >+ "Return build directory of the current PROJECT. >+If the variable `project-build-dir' is defined, this function returns >+it, otherwise it returns the project root. If the defined path is >+relative, this expands it relatively to the project's root" >+ (let ((dir (or project-build-dir >+ (project-build-dir project) >+ (project-root project)))) ;; I assume project-root is absolute >+ (if (file-name-absolute-p dir) >+ dir >+ (expand-file-name dir (project-root project))))) >+ > (cl-defgeneric project-name (project) >- "A human-readable name for the project. >+ "A human-readable name for the PROJECT. > Nominally unique, but not enforced." > (file-name-nondirectory (directory-file-name (project-root project)))) > >@@ -1391,7 +1422,7 @@ project-compile > "Run `compile' in the project root." > (declare (interactive-only compile)) > (interactive) >- (let ((default-directory (project-root (project-current t))) >+ (let ((default-directory (project-get-build-dir (project-current t))) > (compilation-buffer-name-function > (or project-compilation-buffer-name-function > compilation-buffer-name-function))) [-- Attachment #2: project-compile.patch --] [-- Type: text/plain, Size: 4160 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index ac18aceadcf..5a4274d6f68 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -51,6 +51,9 @@ ;; files inside the root must not be considered a part of it). It ;; should be consistent with `project-files'. ;; +;; `project-build-dir' can be overridden if the project backend has some +;; extra information about the project build directory. +;; ;; This list can change in future versions. ;; ;; Transient project: @@ -208,6 +211,22 @@ project-prompter :group 'project :version "30.1") +(defcustom project-build-dir nil + "Build directory for current project. +This is the custom that the user could specify in dir-locals to override +the option specified by the project's backend." + :type 'directory + :safe t + :version "30.1") + +(defcustom project-compile-command nil + "Build command for current project. +This is the custom that the user could specify in dir-locals to override +the option specified by the project's backend." + :type 'directory + :safe t + :version "30.1") + ;;;###autoload (defun project-current (&optional maybe-prompt directory) "Return the project instance in DIRECTORY, defaulting to `default-directory'. @@ -289,8 +308,42 @@ project-external-roots headers search path, load path, class path, and so on." nil) +(cl-defgeneric project-build-dir (_project) + "Return build directory of the current PROJECT. + +This function is intended to be defined by the backend when possible. +Otherwise this returns nil and the `project-compile' command will be +called in the project-root. +If the user defines the directory-local variable `project-build-dir' it +will have precedence over the result of this function." + nil) + +(defun project-get-build-dir (project) + "Return build directory of the current PROJECT. +1. If the variable `project-build-dir' is defined, this function returns +it. 2. Else if the function `project-build-dir' return non-nil. +3. else it return the project-root. +If the defined path is relative, this expands it relatively to the +project's root." + (let ((dir (or project-build-dir ;; variable for dir-locals or connection local vars + (project-build-dir project) ;; backend function + (project-root project)))) ;; I assume project-root is always absolute + (if (file-name-absolute-p dir) + dir + (expand-file-name dir (project-root project))))) + +(cl-defgeneric project-compile-command (_project) + "Return build command of the current PROJECT. + +This function is intended to be defined by the backend when possible. +Otherwise this returns nil and the `project-compile' command will use +the default `compile-command' value. If the user defines the +directory-local variable `project-build-command' it will have preference +over this function and this will be never called." + nil) + (cl-defgeneric project-name (project) - "A human-readable name for the project. + "A human-readable name for the PROJECT. Nominally unique, but not enforced." (file-name-nondirectory (directory-file-name (project-root project)))) @@ -1391,10 +1444,16 @@ project-compile "Run `compile' in the project root." (declare (interactive-only compile)) (interactive) - (let ((default-directory (project-root (project-current t))) - (compilation-buffer-name-function - (or project-compilation-buffer-name-function - compilation-buffer-name-function))) + ;; I am wondering whenever we need to expand connection local + ;; variables at this point... maybe before or inside the let. + (let* ((project (project-current t)) + (default-directory (project-get-build-dir project)) + (compile-command (or project-compile-command + (project-compile-command project) + compile-command)) + (compilation-buffer-name-function + (or project-compilation-buffer-name-function + compilation-buffer-name-function))) (call-interactively #'compile))) (defun project-recompile (&optional edit-command) ^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-03-27 16:38 ` [PATCH] " Ergus @ 2024-03-31 2:41 ` Dmitry Gutov 2024-03-31 21:07 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Dmitry Gutov @ 2024-03-31 2:41 UTC (permalink / raw) To: Ergus; +Cc: emacs-devel Hi Ergus, On 27/03/2024 18:38, Ergus wrote: > Here I attach a very simple patch to allow project out of sources > compilation and project build detection. > > So far I already implemented a very primitive backend [1] for project.el > using these features to detect and compile autotools and cmake projects; > and, at some point I will propose it for elpa. > > But I need to work a bit more on it; and, of course, the functionalities > in the attached patch need to go to vanilla this way or some other > equivalent. I originally suggested a variable that stores a relative file name. But I see that you prefer the fetching of this file name to be more dynamic. Why don't we just make it a function variable, at least at first? Call it 'project-compile-dir`, which would be settable to a string (constant value, to be customized through dir-locals), or a function that either accepts the current project value, or is simply called "inside project root" (with default-directory bound to that value). Alternatively, if you see a need to add additional methods ('project-compile-command'?), it could become a new hook and a new facility (e.g. project-build-functions) which could be structures similarly to project.el, i.e. the hook returns a "project builder" value, and the value has some methods that it can defined/override. Then different build tool backends could be mixed with different project backends more easily. So far I only see one additional method, though, and the constructed compile-command value is relatively simple. Curious to see whether this will get more complex with additional targets. As far as the redefinition of 'project-name' goes, perhaps we'll allow project-vc-name to be a function as well? Or decide on some other way to assign a build tool the name to a project. > Best, > Ergus > > [1] > https://github.com/Ergus/project-multi-mode/blob/master/project-multi-mode.el > > > > On Tue, Mar 19, 2024 at 07:36:35PM +0100, Ergus wrote: >> Hi Dmitry: >> >> Here I attach a very simple approach to add support for out of sources >> compilation in project.el >> >> This is just a POC, but to have some starting point to discuss. >> >> Best, >> Ergus >> >> >> >> On Sun, Mar 17, 2024 at 06:47:43PM +0100, Ergus wrote: >>> On Sun, Mar 17, 2024 at 12:36:44PM +0100, Augusto Stoffel wrote: >>>> On Sat, 16 Mar 2024 at 14:12, Ergus wrote: >>>> >>>>> 5. Project local variables (a man can dream, a man can dream) >>>>> >>>>> There are some situations where we want to have variables shared >>>>> among a >>>>> project. (i.e some output directory, logging option when executing, >>>>> flags, environment variables). >>>>> >>>>> At the moment these options work partially by using directory >>>>> variables. If we have the concept of a "project", maybe it is >>>>> logical to >>>>> have some sort of project scope concept, specially for projects >>>>> sharing >>>>> a common root. >>>> >>>> For Emacs variables, why you think dir-local variables only works >>>> “partially”? >>>> >>>> As to environment variables, they are generally assumed to be global in >>>> Emacs and it goes a bit against the grain to make them buffer-local / >>>> project dependent. Nonetheless, there are packages for that (one is >>>> buffer-env, which I wrote) and they work fine (at least for me). >>>> >>> They work for one directory, but when the project includes multiple >>> roots (project-external-roots) the variables are somehow missing just >>> when jumping with xref to a definition. >>> >>> However, we can ignore this as I mentioned before. >>> >>>>> For example vs-code adds a subdirectory with project variables that >>>>> the >>>>> user (but also any plugin) can refer to in the project's scope. >>>> >>>> Is this meant to store editor configuration or environment >>>> variables? I >>>> guess turning VSCode configuration variables into Emacs alternatives >>>> would be tricky. >>> >>> No please. No interaction-importing from other editors will be >>> maintainable in the long path. >>> >>>> But if this is about env vars and the directory >>>> organization is sensible, then one could configure buffer-env to >>>> interoperate. >>> >>> This is it. The idea is to extend project.el in order to bring more >>> project-oriented features. >>> >>> Lets say: >>> >>> The user (or project.el backend) could specify the `build` directory and >>> the environment that needs to be set to execute the program from the >>> build or bin directory. >>> >>> So with a simple modification of dir-locals.el the user may be capable >>> to run M-x compile (or project-compile), M-x gud-gdb... or being more >>> ambitious M-x project-generate (to call autogen.sh and ./configure or >>> cmake depending of the project-backend) >>> >>> For sure we wont cover the 100% of the projects, but wuth automake and >>> autotools we will be very close (and in the future someone could add >>> other backends for it) >>> >>> >>> >>> >>> > >> commit cfa10dfeac01ae25a7acd6857fae0b377b625779 >> Author: Jimmy Aguilar Mena <kratsbinovish@gmail.com> >> Date: Tue Mar 19 17:57:25 2024 +0100 >> >> Add basic project-build-dir implementation >> >> This is just a dummy prototype to discuss about alternatives. >> >> diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el >> index ac18aceadcf..0ca4ca85566 100644 >> --- a/lisp/progmodes/project.el >> +++ b/lisp/progmodes/project.el >> @@ -51,6 +51,9 @@ >> ;; files inside the root must not be considered a part of it). It >> ;; should be consistent with `project-files'. >> ;; >> +;; `project-build-dir' can be overridden if the project backend has some >> +;; extra information about the project build directory. >> +;; >> ;; This list can change in future versions. >> ;; >> ;; Transient project: >> @@ -208,6 +211,12 @@ project-prompter >> :group 'project >> :version "30.1") >> >> +(defcustom project-build-dir nil >> + "Build directory for current project." >> + :type 'directory >> + :safe t >> + :version "30.1") >> + >> ;;;###autoload >> (defun project-current (&optional maybe-prompt directory) >> "Return the project instance in DIRECTORY, defaulting to >> `default-directory'. >> @@ -289,8 +298,30 @@ project-external-roots >> headers search path, load path, class path, and so on." >> nil) >> >> +(cl-defgeneric project-build-dir (_project) >> + "Return build directory of the current PROJECT. >> + >> +This function is intended to be defined by the backend when possible. >> +Otherwise this returns nil and the `project-compile' command will be >> +called in the project-root. >> +If the user defines the directory-local variable `project-build-dir' it >> +will have precedence over the result of this function." >> + nil) >> + >> +(defun project-get-build-dir (project) >> + "Return build directory of the current PROJECT. >> +If the variable `project-build-dir' is defined, this function returns >> +it, otherwise it returns the project root. If the defined path is >> +relative, this expands it relatively to the project's root" >> + (let ((dir (or project-build-dir >> + (project-build-dir project) >> + (project-root project)))) ;; I assume project-root >> is absolute >> + (if (file-name-absolute-p dir) >> + dir >> + (expand-file-name dir (project-root project))))) >> + >> (cl-defgeneric project-name (project) >> - "A human-readable name for the project. >> + "A human-readable name for the PROJECT. >> Nominally unique, but not enforced." >> (file-name-nondirectory (directory-file-name (project-root project)))) >> >> @@ -1391,7 +1422,7 @@ project-compile >> "Run `compile' in the project root." >> (declare (interactive-only compile)) >> (interactive) >> - (let ((default-directory (project-root (project-current t))) >> + (let ((default-directory (project-get-build-dir (project-current t))) >> (compilation-buffer-name-function >> (or project-compilation-buffer-name-function >> compilation-buffer-name-function))) > ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-03-31 2:41 ` Dmitry Gutov @ 2024-03-31 21:07 ` Ergus 2024-04-01 7:49 ` Dirk-Jan C. Binnema 2024-04-02 21:39 ` Richard Stallman 0 siblings, 2 replies; 57+ messages in thread From: Ergus @ 2024-03-31 21:07 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel Hi Dmitry: On Sun, Mar 31, 2024 at 05:41:24AM +0300, Dmitry Gutov wrote: >Hi Ergus, > >On 27/03/2024 18:38, Ergus wrote: > >>Here I attach a very simple patch to allow project out of sources >>compilation and project build detection. >> >>So far I already implemented a very primitive backend [1] for project.el >>using these features to detect and compile autotools and cmake projects; >>and, at some point I will propose it for elpa. >> >>But I need to work a bit more on it; and, of course, the functionalities >>in the attached patch need to go to vanilla this way or some other >>equivalent. > >I originally suggested a variable that stores a relative file name. >But I see that you prefer the fetching of this file name to be more >dynamic. > Yes, that's actually the point. In out of sources compilation there is a possibility that there will be more than one subdirectory to build, in that case the user may be asked at least once which one to choose. This is also valid to detect the `compile-commands.json' which may have different version in each of the build-dir candidates. https://github.com/Ergus/project-multi-mode/blob/c679d73a26b162e4158f6451027ca94e33faca0b/project-multi-mode.el#L109 >Why don't we just make it a function variable, at least at first? > Because I wanted somehow to follow the project.el schema of using a generic that the backend could optionally define transparently. And make that definition independent from the user config variable, so, the user defined variable takes preference over the generic search performed by the backend which if not defined automatically goes to project root. Somehow adding a custom variable I think interferes with the idea that the backend provides the functionality... But I may be wrong. >Call it 'project-compile-dir`, which would be settable to a string >(constant value, to be customized through dir-locals), or a function >that either accepts the current project value, or is simply called >"inside project root" (with default-directory bound to that value). > I will try this again, but I had some issues before. >Alternatively, if you see a need to add additional methods >('project-compile-command'?), it could become a new hook and a new >facility (e.g. project-build-functions) which could be structures >similarly to project.el, i.e. the hook returns a "project builder" >value, and the value has some methods that it can defined/override. >Then different build tool backends could be mixed with different >project backends more easily. > I would prefer avoid more abstraction layers in the api. We actually need some `project-compile-command' like function, but structuring it with generics and more layer is IMHO adding too much complexity for a public api... Isn't there a simpler alternative? >So far I only see one additional method, though, and the constructed >compile-command value is relatively simple. Curious to see whether >this will get more complex with additional targets. > I added one method and with that I already support autotools and cmake. >As far as the redefinition of 'project-name' goes, perhaps we'll allow >project-vc-name to be a function as well? Or decide on some other way >to assign a build tool the name to a project. > In project-name I actually only changed the docstring, I didn't change anything else. >>Best, >>Ergus >> >>[1] https://github.com/Ergus/project-multi-mode/blob/master/project-multi-mode.el >> >> >> >>On Tue, Mar 19, 2024 at 07:36:35PM +0100, Ergus wrote: >>>Hi Dmitry: >>> >>>Here I attach a very simple approach to add support for out of sources >>>compilation in project.el >>> >>>This is just a POC, but to have some starting point to discuss. >>> >>>Best, >>>Ergus >>> >>> >>> >>>On Sun, Mar 17, 2024 at 06:47:43PM +0100, Ergus wrote: >>>>On Sun, Mar 17, 2024 at 12:36:44PM +0100, Augusto Stoffel wrote: >>>>>On Sat, 16 Mar 2024 at 14:12, Ergus wrote: >>>>> >>>>>>5. Project local variables (a man can dream, a man can dream) >>>>>> >>>>>>There are some situations where we want to have variables >>>>>>shared among a >>>>>>project. (i.e some output directory, logging option when executing, >>>>>>flags, environment variables). >>>>>> >>>>>>At the moment these options work partially by using directory >>>>>>variables. If we have the concept of a "project", maybe it >>>>>>is logical to >>>>>>have some sort of project scope concept, specially for >>>>>>projects sharing >>>>>>a common root. >>>>> >>>>>For Emacs variables, why you think dir-local variables only works >>>>>“partially”? >>>>> >>>>>As to environment variables, they are generally assumed to be global in >>>>>Emacs and it goes a bit against the grain to make them buffer-local / >>>>>project dependent. Nonetheless, there are packages for that (one is >>>>>buffer-env, which I wrote) and they work fine (at least for me). >>>>> >>>>They work for one directory, but when the project includes multiple >>>>roots (project-external-roots) the variables are somehow missing just >>>>when jumping with xref to a definition. >>>> >>>>However, we can ignore this as I mentioned before. >>>> >>>>>>For example vs-code adds a subdirectory with project >>>>>>variables that the >>>>>>user (but also any plugin) can refer to in the project's scope. >>>>> >>>>>Is this meant to store editor configuration or environment >>>>>variables? I >>>>>guess turning VSCode configuration variables into Emacs alternatives >>>>>would be tricky. >>>> >>>>No please. No interaction-importing from other editors will be >>>>maintainable in the long path. >>>> >>>>>But if this is about env vars and the directory >>>>>organization is sensible, then one could configure buffer-env to >>>>>interoperate. >>>> >>>>This is it. The idea is to extend project.el in order to bring more >>>>project-oriented features. >>>> >>>>Lets say: >>>> >>>>The user (or project.el backend) could specify the `build` directory and >>>>the environment that needs to be set to execute the program from the >>>>build or bin directory. >>>> >>>>So with a simple modification of dir-locals.el the user may be capable >>>>to run M-x compile (or project-compile), M-x gud-gdb... or being more >>>>ambitious M-x project-generate (to call autogen.sh and ./configure or >>>>cmake depending of the project-backend) >>>> >>>>For sure we wont cover the 100% of the projects, but wuth automake and >>>>autotools we will be very close (and in the future someone could add >>>>other backends for it) >>>> >>>> >>>> >>>> >>>> >> >>>commit cfa10dfeac01ae25a7acd6857fae0b377b625779 >>>Author: Jimmy Aguilar Mena <kratsbinovish@gmail.com> >>>Date: Tue Mar 19 17:57:25 2024 +0100 >>> >>> Add basic project-build-dir implementation >>> >>> This is just a dummy prototype to discuss about alternatives. >>> >>>diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el >>>index ac18aceadcf..0ca4ca85566 100644 >>>--- a/lisp/progmodes/project.el >>>+++ b/lisp/progmodes/project.el >>>@@ -51,6 +51,9 @@ >>>;; files inside the root must not be considered a part of it). It >>>;; should be consistent with `project-files'. >>>;; >>>+;; `project-build-dir' can be overridden if the project backend has some >>>+;; extra information about the project build directory. >>>+;; >>>;; This list can change in future versions. >>>;; >>>;; Transient project: >>>@@ -208,6 +211,12 @@ project-prompter >>> :group 'project >>> :version "30.1") >>> >>>+(defcustom project-build-dir nil >>>+ "Build directory for current project." >>>+ :type 'directory >>>+ :safe t >>>+ :version "30.1") >>>+ >>>;;;###autoload >>>(defun project-current (&optional maybe-prompt directory) >>> "Return the project instance in DIRECTORY, defaulting to >>>`default-directory'. >>>@@ -289,8 +298,30 @@ project-external-roots >>>headers search path, load path, class path, and so on." >>> nil) >>> >>>+(cl-defgeneric project-build-dir (_project) >>>+ "Return build directory of the current PROJECT. >>>+ >>>+This function is intended to be defined by the backend when possible. >>>+Otherwise this returns nil and the `project-compile' command will be >>>+called in the project-root. >>>+If the user defines the directory-local variable `project-build-dir' it >>>+will have precedence over the result of this function." >>>+ nil) >>>+ >>>+(defun project-get-build-dir (project) >>>+ "Return build directory of the current PROJECT. >>>+If the variable `project-build-dir' is defined, this function returns >>>+it, otherwise it returns the project root. If the defined path is >>>+relative, this expands it relatively to the project's root" >>>+ (let ((dir (or project-build-dir >>>+ (project-build-dir project) >>>+ (project-root project)))) ;; I assume >>>project-root is absolute >>>+ (if (file-name-absolute-p dir) >>>+ dir >>>+ (expand-file-name dir (project-root project))))) >>>+ >>>(cl-defgeneric project-name (project) >>>- "A human-readable name for the project. >>>+ "A human-readable name for the PROJECT. >>>Nominally unique, but not enforced." >>> (file-name-nondirectory (directory-file-name (project-root project)))) >>> >>>@@ -1391,7 +1422,7 @@ project-compile >>> "Run `compile' in the project root." >>> (declare (interactive-only compile)) >>> (interactive) >>>- (let ((default-directory (project-root (project-current t))) >>>+ (let ((default-directory (project-get-build-dir (project-current t))) >>> (compilation-buffer-name-function >>> (or project-compilation-buffer-name-function >>> compilation-buffer-name-function))) >> > > ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-03-31 21:07 ` Ergus @ 2024-04-01 7:49 ` Dirk-Jan C. Binnema 2024-04-01 13:52 ` Ergus 2024-04-02 21:39 ` Richard Stallman 1 sibling, 1 reply; 57+ messages in thread From: Dirk-Jan C. Binnema @ 2024-04-01 7:49 UTC (permalink / raw) To: emacs-devel; +Cc: Dmitry Gutov On Sunday Mar 31 2024, Ergus wrote: > Hi Dmitry: > > On Sun, Mar 31, 2024 at 05:41:24AM +0300, Dmitry Gutov wrote: >>Hi Ergus, >> >>On 27/03/2024 18:38, Ergus wrote: >> >> I originally suggested a variable that stores a relative file name. But I see >> that you prefer the fetching of this file name to be more dynamic. >> > Yes, that's actually the point. In out of sources compilation there is a > possibility that there will be more than one subdirectory to build, in > that case the user may be asked at least once which one to choose. This > is also valid to detect the `compile-commands.json' which may have > different version in each of the build-dir candidates. > > https://github.com/Ergus/project-multi-mode/blob/c679d73a26b162e4158f6451027ca94e33faca0b/project-multi-mode.el#L109 My 0.02: Having separate build-directories seems to be increasingly common (in my bubble I hardly see anything else anymore) Allowing for _multiple_ build-directories is also quit common/useful. E.g., for doing debug/release builds, or for building for different target hw (embedded dev). For me, a daily need. So having direct support for this in project.el would be quite welcome, so I can use that instead of my private hacks. >>Why don't we just make it a function variable, at least at first? >> > Because I wanted somehow to follow the project.el schema of using a > generic that the backend could optionally define transparently. > > And make that definition independent from the user config variable, so, > the user defined variable takes preference over the generic search > performed by the backend which if not defined automatically goes to > project root. Somehow adding a custom variable I think interferes with > the idea that the backend provides the functionality... But I may be > wrong. > >> Call it 'project-compile-dir`, which would be settable to a string (constant >> value, to be customized through dir-locals), or a function that either accepts >> the current project value, or is simply called "inside project root" (with >> default-directory bound to that value). >> > I will try this again, but I had some issues before. > >> Alternatively, if you see a need to add additional methods >> ('project-compile-command'?), it could become a new hook and a new facility >> (e.g. project-build-functions) which could be structures similarly to >> project.el, i.e. the hook returns a "project builder" value, and the value has >> some methods that it can defined/override. Then different build tool backends >> could be mixed with different project backends more easily. >> > I would prefer avoid more abstraction layers in the api. We actually > need some `project-compile-command' like function, but structuring it > with generics and more layer is IMHO adding too much complexity for a > public api... Isn't there a simpler alternative? > >> So far I only see one additional method, though, and the constructed >> compile-command value is relatively simple. Curious to see whether this will >> get more complex with additional targets. >> > I added one method and with that I already support autotools and cmake. (would be nice to add "meson" too!) No immediate opinions on how to implement this, but things I commonly want in projects: - build - run - test - install - flash - debug - clean It's possible of course to "multiplex" with the compile-command and put in a "transient" or something like that; but it'd be nice to handle this directly across projects; also for adding menu / toolbar commands. Guess this is a bit of an open-ended list, so having `project-*-command` may not to be the best. Kind regards, Dirk. -- Dirk-Jan C. Binnema Helsinki, Finland e:djcb@djcbsoftware.nl w:www.djcbsoftware.nl gpg: 6987 9CED 1745 9375 0F14 DA98 11DD FEA9 DCC4 A036 ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-01 7:49 ` Dirk-Jan C. Binnema @ 2024-04-01 13:52 ` Ergus 2024-04-01 15:09 ` Dirk-Jan C. Binnema 2024-04-02 23:23 ` Dmitry Gutov 0 siblings, 2 replies; 57+ messages in thread From: Ergus @ 2024-04-01 13:52 UTC (permalink / raw) To: Dirk-Jan C. Binnema; +Cc: emacs-devel, Dmitry Gutov On Mon, Apr 01, 2024 at 10:49:25AM +0300, Dirk-Jan C. Binnema wrote: >On Sunday Mar 31 2024, Ergus wrote: > >> Hi Dmitry: >> >> On Sun, Mar 31, 2024 at 05:41:24AM +0300, Dmitry Gutov wrote: >>>Hi Ergus, >>> >>>On 27/03/2024 18:38, Ergus wrote: >>> > >>> I originally suggested a variable that stores a relative file name. But I see >>> that you prefer the fetching of this file name to be more dynamic. >>> >> Yes, that's actually the point. In out of sources compilation there is a >> possibility that there will be more than one subdirectory to build, in >> that case the user may be asked at least once which one to choose. This >> is also valid to detect the `compile-commands.json' which may have >> different version in each of the build-dir candidates. >> >> https://github.com/Ergus/project-multi-mode/blob/c679d73a26b162e4158f6451027ca94e33faca0b/project-multi-mode.el#L109 > >My 0.02: Having separate build-directories seems to be increasingly >common (in my bubble I hardly see anything else anymore) > Same for me >Allowing for _multiple_ build-directories is also quit common/useful. >E.g., for doing debug/release builds, or for building for different >target hw (embedded dev). For me, a daily need. > This is actually part of the main goal >So having direct support for this in project.el would be quite welcome, >so I can use that instead of my private hacks. > Projectile already have support for many backends and the implementation is pretty clean. I am doing this because I thing that something so basic must be part of vanilla. >>>Why don't we just make it a function variable, at least at first? >>> >> Because I wanted somehow to follow the project.el schema of using a >> generic that the backend could optionally define transparently. >> >> And make that definition independent from the user config variable, so, >> the user defined variable takes preference over the generic search >> performed by the backend which if not defined automatically goes to >> project root. Somehow adding a custom variable I think interferes with >> the idea that the backend provides the functionality... But I may be >> wrong. >> >>> Call it 'project-compile-dir`, which would be settable to a string (constant >>> value, to be customized through dir-locals), or a function that either accepts >>> the current project value, or is simply called "inside project root" (with >>> default-directory bound to that value). >>> >> I will try this again, but I had some issues before. >> >>> Alternatively, if you see a need to add additional methods >>> ('project-compile-command'?), it could become a new hook and a new facility >>> (e.g. project-build-functions) which could be structures similarly to >>> project.el, i.e. the hook returns a "project builder" value, and the value has >>> some methods that it can defined/override. Then different build tool backends >>> could be mixed with different project backends more easily. >>> >> I would prefer avoid more abstraction layers in the api. We actually >> need some `project-compile-command' like function, but structuring it >> with generics and more layer is IMHO adding too much complexity for a >> public api... Isn't there a simpler alternative? >> >>> So far I only see one additional method, though, and the constructed >>> compile-command value is relatively simple. Curious to see whether this will >>> get more complex with additional targets. >>> >> I added one method and with that I already support autotools and cmake. > >(would be nice to add "meson" too!) > No problem once the feature will be more advanced I can add it to the project-multi backend in my github... >No immediate opinions on how to implement this, but things I commonly >want in projects: > >- build >- run >- test >- install >- flash >- debug >- clean > Lets start with the one common to all: `build' Some others are difficult to support i.e I have no idea what is `flash'. And makefile based projects may not have a clean target defined. The install may be also controversial as it may refer to install in the system or create an install directory. And run is complicated because most projects create multiple outputs, so we need to find some kind of standard method to list them in order to at least ask the user in the first call. As Dmitry said, the multiple targets may be also difficult to handle with this abstraction either to `build only one' (may require completion in the command manually) or to debug (in order to know which target/executable to debug). I am not saying it is impossible, just that I don't have enough knowledge about all the tools and their support for such commands. Also remember that this only applies to specific backends because vc backends know nothing about this, so the commands need to be defined somehow conditionally in M-x according to the backend... That's very far from my elisp capabilities... >It's possible of course to "multiplex" with the compile-command and put >in a "transient" or something like that; but it'd be nice to handle this >directly across projects; also for adding menu / toolbar commands. > >Guess this is a bit of an open-ended list, so having `project-*-command` >may not to be the best. > Agree here, but I am not a good lisper... so probably Dmitry can bring some advanced elisp feature I am not be aware of that could solve this issue. >Kind regards, >Dirk. > >-- >Dirk-Jan C. Binnema Helsinki, Finland >e:djcb@djcbsoftware.nl w:www.djcbsoftware.nl >gpg: 6987 9CED 1745 9375 0F14 DA98 11DD FEA9 DCC4 A036 > ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-01 13:52 ` Ergus @ 2024-04-01 15:09 ` Dirk-Jan C. Binnema 2024-04-01 17:18 ` Ergus 2024-04-02 23:23 ` Dmitry Gutov 1 sibling, 1 reply; 57+ messages in thread From: Dirk-Jan C. Binnema @ 2024-04-01 15:09 UTC (permalink / raw) To: emacs-devel On Monday Apr 01 2024, Ergus wrote: > On Mon, Apr 01, 2024 at 10:49:25AM +0300, Dirk-Jan C. Binnema wrote: >>> I added one method and with that I already support autotools and cmake. >> >>(would be nice to add "meson" too!) >> > No problem once the feature will be more advanced I can add it to the > project-multi backend in my github... Great! For meson support, I found I needed somewhat of a variation on `locate-dominating-file' to find the remotest parent directory that has a meson.build. Guess it's similar to what's needed for cmake. >>No immediate opinions on how to implement this, but things I commonly >>want in projects: >> >>- build >>- run >>- test >>- install >>- flash >>- debug >>- clean >> > Lets start with the one common to all: `build' > > Some others are difficult to support i.e I have no idea what is > `flash'. And makefile based projects may not have a clean target defined. Yes, these are only useful for _some_ projects; currently I have some custom solution to determine the flash command for the current project (if any). But I think it'd be nice to somehow attach the functionality to the current project. Note - it'd indeed be hard to automatically guess/determine this for some project; in many cases, it would probably require the user to configure some project-specific variable to set the commands. > The install may be also controversial as it may refer to install in the > system or create an install directory. > > And run is complicated because most projects create multiple outputs, so > we need to find some kind of standard method to list them in order to at > least ask the user in the first call. As above, some of this might require some project-specific user variables. For comparison e.g. VSCode allows for doing such actions for many projects; Emacs can do that as well, but currently it requires quite a bit of custom tweaking; I'm just saying it'd be nice to integrate that with project.el. Some .project-locals.el could be useful for this. > As Dmitry said, the multiple targets may be also difficult to handle > with this abstraction either to `build only one' (may require > completion in the command manually) or to debug (in order to know > which target/executable to debug). I am not saying it is impossible, > just that I don't have enough knowledge about all the tools and their > support for such commands. > > Also remember that this only applies to specific backends because vc > backends know nothing about this, so the commands need to be defined > somehow conditionally in M-x according to the backend... That's very far > from my elisp capabilities... > >>It's possible of course to "multiplex" with the compile-command and put >>in a "transient" or something like that; but it'd be nice to handle this >>directly across projects; also for adding menu / toolbar commands. >> >>Guess this is a bit of an open-ended list, so having `project-*-command` >>may not to be the best. >> > Agree here, but I am not a good lisper... so probably Dmitry can bring > some advanced elisp feature I am not be aware of that could solve this > issue. Sorry for hi-jacking your useful proposal to propose some more :-) Kind regards, Dirk. -- Dirk-Jan C. Binnema Helsinki, Finland e:djcb@djcbsoftware.nl w:www.djcbsoftware.nl gpg: 6987 9CED 1745 9375 0F14 DA98 11DD FEA9 DCC4 A036 ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-01 15:09 ` Dirk-Jan C. Binnema @ 2024-04-01 17:18 ` Ergus 0 siblings, 0 replies; 57+ messages in thread From: Ergus @ 2024-04-01 17:18 UTC (permalink / raw) To: Dirk-Jan C. Binnema; +Cc: emacs-devel On Mon, Apr 01, 2024 at 06:09:48PM +0300, Dirk-Jan C. Binnema wrote: >On Monday Apr 01 2024, Ergus wrote: > >> On Mon, Apr 01, 2024 at 10:49:25AM +0300, Dirk-Jan C. Binnema wrote: > >>>> I added one method and with that I already support autotools and cmake. >>> >>>(would be nice to add "meson" too!) >>> >> No problem once the feature will be more advanced I can add it to the >> project-multi backend in my github... > >Great! > >For meson support, I found I needed somewhat of a variation on >`locate-dominating-file' to find the remotest parent directory that has >a meson.build. Guess it's similar to what's needed for cmake.� > Yes in project-multi I only need to add a simple entry like this: (:type cmake // will be meson in your case :program "cmake" // name of program to build :root-hint "CMakeLists.txt" // the filename to search in the root dir (gets the top most if nested) :build-hint "CMakeCache.txt" // The file to search in the build dir (searches in root and all root's subdirs) :project-regex "project[[:blank:]]*([[:blank:]]*\\([[:alnum:]]+\\).+)" // Regex to search the project name in :root-hint :compile-command ":program --build ." // A command pattern to build from build-dir; `:program' will be substituted ) :project-regex can also be a function. sadly I don't really have time now to implement another version of the code needed in project.el... Because there is a part in Dmitry's comments I don't really know how to manage to support the workflow I have now... >>>No immediate opinions on how to implement this, but things I commonly >>>want in projects: >>> >>>- build >>>- run >>>- test >>>- install >>>- flash >>>- debug >>>- clean >>> >> Lets start with the one common to all: `build' >> >> Some others are difficult to support i.e I have no idea what is >> `flash'. And makefile based projects may not have a clean target defined. > >Yes, these are only useful for _some_ projects; currently I have some >custom solution to determine the flash command for the current >project (if any). But I think it'd be nice to somehow attach the >functionality to the current project. > >Note - it'd indeed be hard to automatically guess/determine this for >some project; in many cases, it would probably require the user to >configure some project-specific variable to set the commands. > >> The install may be also controversial as it may refer to install in the >> system or create an install directory. >> >> And run is complicated because most projects create multiple outputs, so >> we need to find some kind of standard method to list them in order to at >> least ask the user in the first call. > >As above, some of this might require some project-specific user >variables. > >For comparison e.g. VSCode allows for doing such actions for many >projects; Emacs can do that as well, but currently it requires quite a >bit of custom tweaking; I'm just saying it'd be nice to integrate that >with project.el. > >Some .project-locals.el could be useful for this. > >> As Dmitry said, the multiple targets may be also difficult to handle >> with this abstraction either to `build only one' (may require >> completion in the command manually) or to debug (in order to know >> which target/executable to debug). I am not saying it is impossible, >> just that I don't have enough knowledge about all the tools and their >> support for such commands. >> >> Also remember that this only applies to specific backends because vc >> backends know nothing about this, so the commands need to be defined >> somehow conditionally in M-x according to the backend... That's very far >> from my elisp capabilities... >> >>>It's possible of course to "multiplex" with the compile-command and put >>>in a "transient" or something like that; but it'd be nice to handle this >>>directly across projects; also for adding menu / toolbar commands. >>> >>>Guess this is a bit of an open-ended list, so having `project-*-command` >>>may not to be the best. >>> >> Agree here, but I am not a good lisper... so probably Dmitry can bring >> some advanced elisp feature I am not be aware of that could solve this >> issue. > >Sorry for hi-jacking your useful proposal to propose some more :-) > Not need to sorry... is actually good that someone else also cares about this... ;) >Kind regards, >Dirk. > >-- >Dirk-Jan C. Binnema Helsinki, Finland >e:djcb@djcbsoftware.nl w:www.djcbsoftware.nl >gpg: 6987 9CED 1745 9375 0F14 DA98 11DD FEA9 DCC4 A036 > ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-01 13:52 ` Ergus 2024-04-01 15:09 ` Dirk-Jan C. Binnema @ 2024-04-02 23:23 ` Dmitry Gutov 2024-04-03 19:47 ` Ergus 2024-04-06 2:05 ` Ergus 1 sibling, 2 replies; 57+ messages in thread From: Dmitry Gutov @ 2024-04-02 23:23 UTC (permalink / raw) To: Ergus, Dirk-Jan C. Binnema; +Cc: emacs-devel On 01/04/2024 16:52, Ergus wrote: >> So having direct support for this in project.el would be quite welcome, >> so I can use that instead of my private hacks. >> > Projectile already have support for many backends and the implementation > is pretty clean. I am doing this because I thing that something so basic > must be part of vanilla. Speaking of Projectile, it has this block of definitions of "project types". Which could maybe better called "build tool types" in the context of this discussion. It would be nice if we could port them over to a design which would be useable by both Projectile and project.el (and together with other project.el backends), rather than having every project backend re-implement these settings, or re-enumerate the supported types. That's why the idea of orthogonal APIs seems appealing to me (the current one for file listing and root finding; the new one for build tools, and compiling, and running, I guess). Until we've drawn up some design for the latter, though, maybe a customizable function variable will suffice. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-02 23:23 ` Dmitry Gutov @ 2024-04-03 19:47 ` Ergus 2024-04-06 2:05 ` Ergus 1 sibling, 0 replies; 57+ messages in thread From: Ergus @ 2024-04-03 19:47 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Dirk-Jan C. Binnema, emacs-devel Hi Dmitry: So far I Think I understood part of your las email about functionality. On Wed, Apr 03, 2024 at 02:23:03AM +0300, Dmitry Gutov wrote: >On 01/04/2024 16:52, Ergus wrote: >>>So having direct support for this in project.el would be quite welcome, >>>so I can use that instead of my private hacks. >>> >>Projectile already have support for many backends and the implementation >>is pretty clean. I am doing this because I thing that something so basic >>must be part of vanilla. > >Speaking of Projectile, it has this block of definitions of "project >types". Which could maybe better called "build tool types" in the >context of this discussion. > >It would be nice if we could port them over to a design which would be >useable by both Projectile and project.el (and together with other >project.el backends), rather than having every project backend >re-implement these settings, or re-enumerate the supported types. > Their design is actually fine, but I would prefer to keep things simpler in the api side because project is intended to be more general. Their use case adds too many functions in order to register, call, test and generate the different backends I thing it is actually too much for vanilla. If we want that complexity maybe is better to retake the last year discussion you mentioned before: https://lists.gnu.org/archive/html/emacs-devel/2023-05/msg00509.html But adding that will require also parallel work and code in order to integrate with project.el. >That's why the idea of orthogonal APIs seems appealing to me (the >current one for file listing and root finding; the new one for build >tools, and compiling, and running, I guess). > I would probably insist in a simpler basic feature still in the current project.el. I can't see the features as a separated thing. What I would probably propose here is (maybe) to move the vc-backend to it's own file as a separated package in order to keep the general api separated from the "plugin". So if a developer wants to create a backend it is clear whats needed and what the standard implementation example... >Until we've drawn up some design for the latter, though, maybe a >customizable function variable will suffice. > What I have in mind as now is to add a variable and a method that can be both optionally defined. The method defined by backends and the variable by the user (maybe in dir-locals). This way the backends won't be forced to define any of these if compilation is not supported (i.e vs-backend) or if the project is for a non-compilable languaje (i.e an hypothetic python project) project-compile-info accepts a second variable that in this case expects 'dir or 'compile-cmd in any case when not implemented the function gives null and the caller (compile in this case) falls back to the default values. This can accept any other command like 'generate-cmd 'test-cmd and so on. In the future we can define any other random command relying on these So far the only we need for compilation is more or less this: ``` diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index a10e24f3e28..9d77d5452f3 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -290,8 +290,29 @@ project-external-roots headers search path, load path, class path, and so on." nil) +(cl-defgeneric project-compile-info (_project _info) + "Return build information of the current PROJECT. + +This function is intended to be defined by the backend when possible. +Otherwise this returns nil and the `project-compile' command will use +the default values. +The current valid values for INFO are `dir' and `compile-cmd'" + nil) + +(defun project-get-build-dir (project) + "Return absolute build directory for the current PROJECT. +1. Tries the generic function `project-compile-info' with info='dir. +2. else it return the project-root. +If the defined path is relative, this expands it relatively to the +project's root." + (let ((dir (or (project-compile-info project 'dir) ;; backend function + (project-root project)))) ;; I assume project-root is always absolute + (if (file-name-absolute-p dir) + dir + (expand-file-name dir (project-root project))))) @@ -1392,10 +1413,15 @@ project-compile "Run `compile' in the project root." (declare (interactive-only compile)) (interactive) - (let ((default-directory (project-root (project-current t))) - (compilation-buffer-name-function - (or project-compilation-buffer-name-function - compilation-buffer-name-function))) + ;; I am wondering whenever we need to expand connection local + ;; variables at this point... maybe before or inside the let. + (let* ((project (project-current t)) + (default-directory (project-get-build-dir project)) + (compile-command (or (project-compile-info project 'compile-cmd) + compile-command)) + (compilation-buffer-name-function + (or project-compilation-buffer-name-function + compilation-buffer-name-function))) (call-interactively #'compile))) ``` Finally the only missing detail is user side configuration... I was thinking in a plist defconst (similar to the approach in eglot-workspace-configuration) so the user can set it completelly or partially and we only need to do: (or (plist-get project-info-plist 'compile-cmd) (project-compile-info project 'compile-cmd) compile-command) In this way the user only has one variable to set in the config with all the parameters optional as well which stays easy, simple in implementation and with a predictable behavior. WDYT?? Best, Ergus ^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-02 23:23 ` Dmitry Gutov 2024-04-03 19:47 ` Ergus @ 2024-04-06 2:05 ` Ergus 2024-04-14 1:44 ` Dmitry Gutov 1 sibling, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-06 2:05 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 791 bytes --] Hi Dmitry: Here I attach a new patch with what I think is the best approach to handle the extra info for projects. This implementation is pretty simple for both sides (user, project.el and backends) and uses your main idea of the generics + a custom. However I decided not to use only the custom as you suggested, because considering the project initialization it will require a complex and error prone approach to initalize the backend variables correctly (for example, when some buffers are already open). With this implementation the backends only need to define the optional generic specializations and the policy is pretty simple to explain (see the doc strings). I also modifies the backend project on github to match this new api, so, you can check it as well. WDYT? Best, Ergus [-- Attachment #2: project-extra-info.patch --] [-- Type: text/plain, Size: 5481 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index da211566a3b..1986c14e861 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -51,6 +51,16 @@ ;; files inside the root must not be considered a part of it). It ;; should be consistent with `project-files'. ;; +;; `project-extra-info' is a user custom variable and a method to +;; specify extra project information like build command or equivalent. +;; The variable is a plist were the values can be strings or functions +;; that receive the project-current as argument. The +;; `project-extra-info' expect project current as first parameter and an +;; extra parameter equivalent to the plist key. The user defined plist +;; takes precedence over the backend defined methods, but all the +;; specializations are optional and the functions calling them may +;; provide conditions in case both are undefined. +;; ;; This list can change in future versions. ;; ;; Transient project: @@ -229,8 +239,8 @@ project-current of the project instance object." (unless directory (setq directory (or project-current-directory-override default-directory))) - (let* ((non-essential (not maybe-prompt)) - (pr (project--find-in-directory directory))) + (let ((pr (project--find-in-directory directory)) + (non-essential (not maybe-prompt))) (cond (pr) ((unless project-current-directory-override @@ -290,8 +300,54 @@ project-external-roots headers search path, load path, class path, and so on." nil) +(defcustom project-extra-info nil + "Project extra info defined in user space. + +This is intended to be set by the user. This is expected to be a plist +with key entries for compile. At the moment the implemented keys are +`:compile-command' and `:compile-dir'. The entries may be either string +constants, paths or functions. This custom has a symmetric generic +method with the same name that are intended to be implemented by the +project backends. When this variable is defined it takes precedence +over the backend methods." + :safe t + :version "30.1" + :type '(plist :key-type (choice (const :compile-dir) + (const :compile-command)) + :value-type (choice string + directory + function))) + +(cl-defgeneric project-extra-info (_project _info) + "Return extra INFO for the current PROJECT. + +This function is intended to be defined by the backend when needed. +Otherwise this returns nil and the `project-compile' command will use +some default values. The current valid values for INFO are the same key +types in project-compile-info: `:compile-dir' and `:compile-command' +This method is independent from the custom variable with same name +because project.el initializes itself lazily and variable propagation +within directories and buffers already open will require too much work +in the user side potentially more error prone." + nil) + +(defun project--get-extra-info (project info) + "Steps to get PROJECT's INFO internally. +1. Parse the user defined variable `project-compile-info'. If the key +exists: + a. Check if it is a function and call it passing project as the first +parameter. + b. If the key is a string return it as is. + c. Otherwise return nil. +2. Else call the backend defined method `project-compile-info'." + (if-let ((value (plist-get project-extra-info info))) + (cond ((functionp value) (funcall value project)) + ((stringp info) info) + (t nil)) + (project-extra-info project info))) + (cl-defgeneric project-name (project) - "A human-readable name for the project. + "A human-readable name for the PROJECT. Nominally unique, but not enforced." (file-name-nondirectory (directory-file-name (project-root project)))) @@ -1389,13 +1445,26 @@ project-compilation-buffer-name-function ;;;###autoload (defun project-compile () - "Run `compile' in the project root." + "Run `compile' in the project build directory. +When the variable `project-extra-info' contains the entries +`:compile-dir' or `:compile-command' or the project backend specializes +the method `project-extra-info' for those values; then this command uses +that instead of the default: `project-root' and `compile-command'." (declare (interactive-only compile)) (interactive) - (let ((default-directory (project-root (project-current t))) - (compilation-buffer-name-function - (or project-compilation-buffer-name-function - compilation-buffer-name-function))) + ;; I am wondering whenever we need to expand connection local + ;; variables at this point... maybe before or inside the let. + (let* ((project (project-current t)) + (dir (or (project--get-extra-info project :compile-dir) + (project-root project))) + (default-directory (if (file-name-absolute-p dir) + dir + (expand-file-name dir (project-root project)))) + (compile-command (or (project--get-extra-info project :compile-command) + compile-command)) + (compilation-buffer-name-function + (or project-compilation-buffer-name-function + compilation-buffer-name-function))) (call-interactively #'compile))) (defun project-recompile (&optional edit-command) ^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-06 2:05 ` Ergus @ 2024-04-14 1:44 ` Dmitry Gutov 2024-04-16 14:56 ` Ergus 2024-04-22 17:05 ` Ergus 0 siblings, 2 replies; 57+ messages in thread From: Dmitry Gutov @ 2024-04-14 1:44 UTC (permalink / raw) To: Ergus; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1020 bytes --] Hi Ergus! On 06/04/2024 05:05, Ergus wrote: > Here I attach a new patch with what I think is the best approach to > handle the extra info for projects. This implementation is pretty simple > for both sides (user, project.el and backends) and uses your main idea > of the generics + a custom. > > However I decided not to use only the custom as you suggested, because > considering the project initialization it will require a complex and > error prone approach to initalize the backend variables correctly (for > example, when some buffers are already open). > > With this implementation the backends only need to define the optional > generic specializations and the policy is pretty simple to explain (see > the doc strings). > > I also modifies the backend project on github to match this new api, so, > you can check it as well. How about the idea with the orthogonal hook, then, as in the attached patch? Something I described before. I think your github code would be easy enough to adapt to use it. WDYT? [-- Attachment #2: project-build-functions.diff --] [-- Type: text/x-patch, Size: 1996 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 000a05804a8..bd1264b5525 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1387,15 +1387,33 @@ project-compilation-buffer-name-function project-prefixed-buffer-name) (function :tag "Custom function"))) +(defvar project-build-functions nil + "Special hook to find the project build configuration. +Each functions on this hook is called in turn with one +argument (project), and should return either nil to mean that it is not +applicable, or a plist with build configuration. + +The configuration can contain keys such as `:compile-dir', +`:compile-command', or others.") + ;;;###autoload (defun project-compile () - "Run `compile' in the project root." + "Run `compile' in the project build directory. +Uses the `project-build-functions' hook to determine the compile command +and the directory to run it in." (declare (interactive-only compile)) (interactive) - (let ((default-directory (project-root (project-current t))) - (compilation-buffer-name-function - (or project-compilation-buffer-name-function - compilation-buffer-name-function))) + (let* ((project (project-current t)) + (build-config (run-hook-with-args 'project-build-functions project)) + (default-directory (if (plist-get build-config :compile-dir) + (expand-file-name (plist-get build-config :compile-dir) + (project-root project)) + default-directory)) + (compile-command (or (plist-get build-config :compile-command) + compile-command)) + (compilation-buffer-name-function + (or project-compilation-buffer-name-function + compilation-buffer-name-function))) (call-interactively #'compile))) (defun project-recompile (&optional edit-command) ^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-14 1:44 ` Dmitry Gutov @ 2024-04-16 14:56 ` Ergus 2024-04-22 17:05 ` Ergus 1 sibling, 0 replies; 57+ messages in thread From: Ergus @ 2024-04-16 14:56 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel Hi Dmitry: Sorry for th delay with this On Sun, Apr 14, 2024 at 04:44:36AM +0300, Dmitry Gutov wrote: >Hi Ergus! > >On 06/04/2024 05:05, Ergus wrote: > >>Here I attach a new patch with what I think is the best approach to >>handle the extra info for projects. This implementation is pretty simple >>for both sides (user, project.el and backends) and uses your main idea >>of the generics + a custom. >> >>However I decided not to use only the custom as you suggested, because >>considering the project initialization it will require a complex and >>error prone approach to initalize the backend variables correctly (for >>example, when some buffers are already open). >> >>With this implementation the backends only need to define the optional >>generic specializations and the policy is pretty simple to explain (see >>the doc strings). >> >>I also modifies the backend project on github to match this new api, so, >>you can check it as well. > >How about the idea with the orthogonal hook, then, as in the attached >patch? Something I described before. > >I think your github code would be easy enough to adapt to use it. > >WDYT? The main idea is somehow the same, but IMHO I think that this approach complicates the user config and backend implementation being also less efficient and scalable (we will need a new hook for every new similar feature). There is no need to separate the backend from the build, and after some tests, I find the cl-defgeneric behavior more predictable and simpler to debug than using a function hook. Your initial idea implemented like (cl-defgeneric project-extra-info (_project _info) ...) In my opinion is simpler and more scalable (while could be recycled to provide also other existing functionalities like project-compilation-buffer-name-function. All the generic implementations become then optional which is very desired for the general purpose. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-14 1:44 ` Dmitry Gutov 2024-04-16 14:56 ` Ergus @ 2024-04-22 17:05 ` Ergus 2024-04-22 18:48 ` Ergus 1 sibling, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-22 17:05 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel Hi Juri: Give a look to this: https://github.com/mohkale/projection It seems similar to what we may consider to support in vanilla. OR at least provide the interactive interface wrapper functions in order to make project.el a bit more standard. On Sun, Apr 14, 2024 at 04:44:36AM GMT, Dmitry Gutov wrote: >Hi Ergus! > >On 06/04/2024 05:05, Ergus wrote: > >>Here I attach a new patch with what I think is the best approach to >>handle the extra info for projects. This implementation is pretty simple >>for both sides (user, project.el and backends) and uses your main idea >>of the generics + a custom. >> >>However I decided not to use only the custom as you suggested, because >>considering the project initialization it will require a complex and >>error prone approach to initalize the backend variables correctly (for >>example, when some buffers are already open). >> >>With this implementation the backends only need to define the optional >>generic specializations and the policy is pretty simple to explain (see >>the doc strings). >> >>I also modifies the backend project on github to match this new api, so, >>you can check it as well. > >How about the idea with the orthogonal hook, then, as in the attached >patch? Something I described before. > >I think your github code would be easy enough to adapt to use it. > >WDYT? ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-22 17:05 ` Ergus @ 2024-04-22 18:48 ` Ergus 2024-04-22 21:20 ` Mohsin Kaleem 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-22 18:48 UTC (permalink / raw) To: mohkale; +Cc: emacs-devel Adding Mohsin Kaleem to the discussion. On Mon, Apr 22, 2024 at 07:05:20PM GMT, Ergus wrote: >Hi Juri: > >Give a look to this: > >https://github.com/mohkale/projection > >It seems similar to what we may consider to support in vanilla. OR at >least provide the interactive interface wrapper functions in order to >make project.el a bit more standard. > >On Sun, Apr 14, 2024 at 04:44:36AM GMT, Dmitry Gutov wrote: >>Hi Ergus! >> >>On 06/04/2024 05:05, Ergus wrote: >> >>>Here I attach a new patch with what I think is the best approach to >>>handle the extra info for projects. This implementation is pretty simple >>>for both sides (user, project.el and backends) and uses your main idea >>>of the generics + a custom. >>> >>>However I decided not to use only the custom as you suggested, because >>>considering the project initialization it will require a complex and >>>error prone approach to initalize the backend variables correctly (for >>>example, when some buffers are already open). >>> >>>With this implementation the backends only need to define the optional >>>generic specializations and the policy is pretty simple to explain (see >>>the doc strings). >>> >>>I also modifies the backend project on github to match this new api, so, >>>you can check it as well. >> >>How about the idea with the orthogonal hook, then, as in the >>attached patch? Something I described before. >> >>I think your github code would be easy enough to adapt to use it. >> >>WDYT? > > > ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-22 18:48 ` Ergus @ 2024-04-22 21:20 ` Mohsin Kaleem 2024-04-23 15:17 ` Ergus 2024-04-26 0:47 ` Dmitry Gutov 0 siblings, 2 replies; 57+ messages in thread From: Mohsin Kaleem @ 2024-04-22 21:20 UTC (permalink / raw) To: Ergus; +Cc: emacs-devel Ergus <spacibba@aol.com> 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 ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-22 21:20 ` Mohsin Kaleem @ 2024-04-23 15:17 ` Ergus 2024-04-23 19:26 ` Mohsin Kaleem 2024-04-26 0:47 ` Dmitry Gutov 1 sibling, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-23 15:17 UTC (permalink / raw) To: Mohsin Kaleem; +Cc: emacs-devel Hi: On Mon, Apr 22, 2024 at 10:20:32PM GMT, Mohsin Kaleem wrote: >Ergus <spacibba@aol.com> 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 give it a look. I am aware of cmake presets, but we don't even support cmake or out of sources compilation yet, so I tink that supporting the most basic cmake setup will be already a step forward. >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 :-). > Yes, that's actually the current approach in my POC code. after some fight with rust projects. However, the difference on moving or not is so simple that it doesn't even represent a difficulty. >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. > This implies removing many of the features project.el already has (project-compile, project-eshell, project-compile-buffer-name-function) + somehow create another level of abstraction over project.el... The initial basic commands (config, build, test/run) seems to be common, even in python projects it usually needs to get dependencies, create virtualenvs and so on. However if a project does not support a build command a simple message can solve it easily. Initially we are not even supporting the generate/configure, and the functionality is limited to: recognize compile and test already generated projects; but using some very primitive heuristics. More complex setups I thing must be left to more specialized external projects. These seems limiting, but it is much more than what we already have now. >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 :-(. > FWIK every directory may have a CMakeLists.txt, but they need to have a project() entry to be considered a project's CMake. The search is actually unavoidable and the regex check actually solves the race conditions. I know that the search is not efficient, but with a couple of optimizations if works very well even with tramp. Nested projects is something very common these days and supporting them in project.el is part of another parallel discussion going on already (very slowly btw). For now it is save enough to find the top-most one as it is what the default backend does. It will probably fit a high percent of all projects around. >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. > More or less the same idea; I use with plist. I think they a bit simpler, but the same underground. I tend to avoid eioio because I have heard some performance complains (don't know if they are justified) but also because plists are somehow more flexible in some aspects. >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 > Actually I am not trying to do anything so fancy. We cannot go from 0 to 100 in a single pass. If we start 1. recognizing projects backends and giving a better compile-command for them in the right place and to the right build-dir is a good step forward compared to what we have. Then we talk about test and finally we can consider the generate one. >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). > At the moment project.el only handles one backend at the time. I made a simple workaround to extend it a bit, but that is a bit tricky and at this point simplicity matters. Otherwise we end up with an inefficient and complex interface easy to break and hard to make it work. >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 > Ergus ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-23 15:17 ` Ergus @ 2024-04-23 19:26 ` Mohsin Kaleem 0 siblings, 0 replies; 57+ messages in thread From: Mohsin Kaleem @ 2024-04-23 19:26 UTC (permalink / raw) To: Ergus; +Cc: emacs-devel Ergus <spacibba@aol.com> writes: > I'll give it a look. I am aware of cmake presets, but we don't even > support cmake or out of sources compilation yet, so I tink that > supporting the most basic cmake setup will be already a step forward. We being the projects you work on? My suggestion was more for automating how you set build configurations. Supporting that in Emacs is separate but still useful. It's just which directory you configure to and build in is yet another part of this instead of some custom thing only Emacs understands. > Yes, that's actually the current approach in my POC code. after some > fight with rust projects. However, the difference on moving or not is so > simple that it doesn't even represent a difficulty. Just moving is easy, but a interface for that that isn't confusing would probably be a lot harder. For example you can switch to a compilation buffer and run cd and recompile and that should work. But it's much easier to just see the command containing the non-common directory it needs to run in. > This implies removing many of the features project.el already has > (project-compile, project-eshell, project-compile-buffer-name-function) > + somehow create another level of abstraction over project.el... I think we probably should. There's a lot of builtin Emacs functionality which is just duplicating standard things in subtly different ways. project-other-{window,tab}* for example. Embark at least supercedes this IMO because it generalises the selection backend from the end user action. In this case project-compile, project-eshell, etc. If this was being done today I'd probably just define a 'project-run-from-root' helper and let the end users alias it to a command if they think its useful. Like so: (defalias 'project-compile! (project-run-from-root #'compile)) But I digress. > The initial basic commands (config, build, test/run) seems to be common, > even in python projects it usually needs to get dependencies, create > virtualenvs and so on. However if a project does not support a build > command a simple message can solve it easily. I agree, but my point was this doesn't really align with anything else project.el does atm. Listing files for a project is orthoganal to which "configure command" makes sense for whatever kind of project this looks like. And necessarily multiple configure commands may make sense at once. > FWIK every directory may have a CMakeLists.txt, but they need to have a > project() entry to be considered a project's CMake. The search is > actually unavoidable and the regex check actually solves the race > conditions. > > I know that the search is not efficient, but with a couple of > optimizations if works very well even with tramp. This aligns with what I know but also that a encompassing CMake with a project can depend on a sub-directories CMake with a project. So if you just configure and build the parent project it'll configure and build all sub-projects. I'm not sure when you'd not want to do this, if the projects have overlapping targets perhaps... but at that point you should probably just move them to independent projects because their already that. > Nested projects is something very common these days and supporting them > in project.el is part of another parallel discussion going on already > (very slowly btw). I have yet to encounter any so I'll assume you're right :-). > More or less the same idea; I use with plist. I think they a bit > simpler, but the same underground. I tend to avoid eioio because I have > heard some performance complains (don't know if they are justified) but > also because plists are somehow more flexible in some aspects. I haven't noticed any performance issues at least in my limited usage of them. > Actually I am not trying to do anything so fancy. We cannot go from 0 to > 100 in a single pass. If we start 1. recognizing projects backends and > giving a better compile-command for them in the right place and to the > right build-dir is a good step forward compared to what we have. Then we > talk about test and finally we can consider the generate one. You should probably keep in mind sometimes there's a feed forward mechanism in these things. CMake for example requires you to setup a file prior to configuring if you want to introspect about the build configuration and available targets. It might help to keep this in mind, in my case I had to add a hook mechanism for all of these commands after the fact to generate and keep this file in sync. [1]: https://cmake.org/cmake/help/latest/manual/cmake-file-api.7.html > At the moment project.el only handles one backend at the time. I made a > simple workaround to extend it a bit, but that is a bit tricky and at > this point simplicity matters. Otherwise we end up with an inefficient > and complex interface easy to break and hard to make it work. This is probably another reason this should be orthogonal to project.el. The project backend is something well defined like a git repo. The project type backend is whatever arbitrary marker communicates what the project type is. -- Mohsin Kaleem ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-22 21:20 ` Mohsin Kaleem 2024-04-23 15:17 ` Ergus @ 2024-04-26 0:47 ` Dmitry Gutov 1 sibling, 0 replies; 57+ messages in thread From: Dmitry Gutov @ 2024-04-26 0:47 UTC (permalink / raw) To: Mohsin Kaleem, Ergus; +Cc: emacs-devel Hi Mohsin, On 23/04/2024 00:20, Mohsin Kaleem wrote: > 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). That's a great point. And your project looks very nice. I wonder how we could advertise it better, so users could have a quicker access to build tool integration. As a next step for this discussion, I'm curious what's missing in "projection" (nice name, though not very discoverable, alas) from Ergus's POV. I.e. how far is it from supporting his workflows. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-03-31 21:07 ` Ergus 2024-04-01 7:49 ` Dirk-Jan C. Binnema @ 2024-04-02 21:39 ` Richard Stallman 2024-04-02 22:43 ` Dr. Arne Babenhauserheide 2024-04-03 10:40 ` Konstantin Kharlamov 1 sibling, 2 replies; 57+ messages in thread From: Richard Stallman @ 2024-04-02 21:39 UTC (permalink / raw) To: Ergus; +Cc: dmitry, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] What does "Project out of sources compilation" mean? I am not sure how to parse that, let alone determine what it signfies. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-02 21:39 ` Richard Stallman @ 2024-04-02 22:43 ` Dr. Arne Babenhauserheide 2024-04-05 21:40 ` Richard Stallman 2024-04-03 10:40 ` Konstantin Kharlamov 1 sibling, 1 reply; 57+ messages in thread From: Dr. Arne Babenhauserheide @ 2024-04-02 22:43 UTC (permalink / raw) To: rms; +Cc: Ergus, dmitry, emacs-devel [-- Attachment #1: Type: text/plain, Size: 529 bytes --] Richard Stallman <rms@gnu.org> writes: > What does "Project out of sources compilation" mean? > I am not sure how to parse that, let alone determine what it signfies. That usually means that the compilation happens in a directory which is not the source directory (similar to how make distcheck does it). In this case that the build command is issued in a dedicated build directory which is not the sources root. Best wishes, Arne -- Unpolitisch sein heißt politisch sein, ohne es zu merken. draketo.de [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 1125 bytes --] ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-02 22:43 ` Dr. Arne Babenhauserheide @ 2024-04-05 21:40 ` Richard Stallman 0 siblings, 0 replies; 57+ messages in thread From: Richard Stallman @ 2024-04-05 21:40 UTC (permalink / raw) To: Dr. Arne Babenhauserheide; +Cc: spacibba, dmitry, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > What does "Project out of sources compilation" mean? > > I am not sure how to parse that, let alone determine what it signfies. > That usually means that the compilation happens in a directory which is > not the source directory (similar to how make distcheck does it). Thanks. I've been building Emacs that way for half my life, but I could not tell that the phrase should be parsed that way. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-02 21:39 ` Richard Stallman 2024-04-02 22:43 ` Dr. Arne Babenhauserheide @ 2024-04-03 10:40 ` Konstantin Kharlamov 2024-04-03 11:45 ` Eli Zaretskii 1 sibling, 1 reply; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-03 10:40 UTC (permalink / raw) To: rms, Ergus; +Cc: dmitry, emacs-devel On Tue, 2024-04-02 at 17:39 -0400, Richard Stallman wrote: > [[[ To any NSA and FBI agents reading my email: please consider > ]]] > [[[ whether defending the US Constitution against all enemies, > ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. > ]]] > > What does "Project out of sources compilation" mean? > I am not sure how to parse that, let alone determine what it > signfies. In Emacs terms, if you enter Emacs repo and execute mkdir build && cd build && ../configure && make it will be an "out of sources compilation", because all artifacts¹ will be inside this `build` dir rather than being scattered all over the repo. 1: Emacs does not fully support it though, because while object files and configs do end up inside `build`, however `*.elc` files are still scattered all over the repo. But I hope you get the idea. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 10:40 ` Konstantin Kharlamov @ 2024-04-03 11:45 ` Eli Zaretskii 2024-04-03 13:31 ` Konstantin Kharlamov 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-03 11:45 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: rms, spacibba, dmitry, emacs-devel > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > Cc: dmitry@gutov.dev, emacs-devel@gnu.org > Date: Wed, 03 Apr 2024 13:40:59 +0300 > > 1: Emacs does not fully support it though, because while object files > and configs do end up inside `build`, however `*.elc` files are still > scattered all over the repo. But I hope you get the idea. The *.elc files are considered part of the source tree (they are in the release tarball, and are portable, so no need to rebuild them when changing some configuration options). Thus, Emacs does "fully support it". ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 11:45 ` Eli Zaretskii @ 2024-04-03 13:31 ` Konstantin Kharlamov 2024-04-03 14:11 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-03 13:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rms, spacibba, dmitry, emacs-devel On Wed, 2024-04-03 at 14:45 +0300, Eli Zaretskii wrote: > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > Cc: dmitry@gutov.dev, emacs-devel@gnu.org > > Date: Wed, 03 Apr 2024 13:40:59 +0300 > > > > 1: Emacs does not fully support it though, because while object > > files > > and configs do end up inside `build`, however `*.elc` files are > > still > > scattered all over the repo. But I hope you get the idea. > > The *.elc files are considered part of the source tree (they are in > the release tarball, and are portable, so no need to rebuild them > when > changing some configuration options). They are generated during compilation and are not commited into git. That makes them build artifacts. The fact they're distributed in release tarballs does not make it less true. Distributing them in tarballs is not strictly necessary, exactly because they can be generated by anyone. Having .elc files in the source tree results in problems when a user created a dir `build-feature1` for one feature branch, and a dir `build-feature2` for another; and then `build-feature1` somehow ends up having "feature2". Which is because it's using build artifacts that are outside `build-feature1`. In fact, I myself has experienced some problems due to that while researching `61960` bug and then later making a separate build dir for something else. I don't remember details, but it has been something with the fact that elc files are outside build dir, and then for some reason Emacs hasn't been regenerating them or something like that (Idk exactly what was up with them, I didn't dig into it). Thus, Emacs certainly does not fully support "out of tree" builds. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 13:31 ` Konstantin Kharlamov @ 2024-04-03 14:11 ` Eli Zaretskii 2024-04-03 15:00 ` Konstantin Kharlamov 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-03 14:11 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: rms, spacibba, dmitry, emacs-devel > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, emacs-devel@gnu.org > Date: Wed, 03 Apr 2024 16:31:30 +0300 > > On Wed, 2024-04-03 at 14:45 +0300, Eli Zaretskii wrote: > > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > > Cc: dmitry@gutov.dev, emacs-devel@gnu.org > > > Date: Wed, 03 Apr 2024 13:40:59 +0300 > > > > > > 1: Emacs does not fully support it though, because while object > > > files > > > and configs do end up inside `build`, however `*.elc` files are > > > still > > > scattered all over the repo. But I hope you get the idea. > > > > The *.elc files are considered part of the source tree (they are in > > the release tarball, and are portable, so no need to rebuild them > > when > > changing some configuration options). > > They are generated during compilation and are not commited into git. > That makes them build artifacts. How is this relevant to whether or not Emacs supports out of tree builds? Building from Git is a special kind of activity; it has its own INSTALL file and _must_ build some of the files in the source tree. Are you aware of many projects whose build from Git can be done without first populating the source tree with some files? Heck, you don't even have the configure script when you clone the repository, and out-of-tree build works by invoking the configure script from a directory _other_ than the one where the script lives. Right? > The fact they're distributed in release tarballs does not make it > less true. Distributing them in tarballs is not strictly necessary, > exactly because they can be generated by anyone. Not true. > Having .elc files in the source tree results in problems when a user > created a dir `build-feature1` for one feature branch, and a dir > `build-feature2` for another; and then `build-feature1` somehow ends up > having "feature2". Which is because it's using build artifacts that > are outside `build-feature1`. Again, not relevant to the aspect on which I commented. > Thus, Emacs certainly does not fully support "out of tree" builds. It does. You are just talking about a very different kind of "out of tree build". ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 14:11 ` Eli Zaretskii @ 2024-04-03 15:00 ` Konstantin Kharlamov 2024-04-03 15:47 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-03 15:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rms, spacibba, dmitry, emacs-devel On Wed, 2024-04-03 at 17:11 +0300, Eli Zaretskii wrote: > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, > > emacs-devel@gnu.org > > Date: Wed, 03 Apr 2024 16:31:30 +0300 > > > > On Wed, 2024-04-03 at 14:45 +0300, Eli Zaretskii wrote: > > > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > > > Cc: dmitry@gutov.dev, emacs-devel@gnu.org > > > > Date: Wed, 03 Apr 2024 13:40:59 +0300 > > > > > > > > 1: Emacs does not fully support it though, because while object > > > > files > > > > and configs do end up inside `build`, however `*.elc` files are > > > > still > > > > scattered all over the repo. But I hope you get the idea. > > > > > > The *.elc files are considered part of the source tree (they are > > > in > > > the release tarball, and are portable, so no need to rebuild them > > > when > > > changing some configuration options). > > > > They are generated during compilation and are not commited into > > git. > > That makes them build artifacts. > > How is this relevant to whether or not Emacs supports out of tree > builds? Directly: the point of "out of tree build" is encapsulating build artifacts in the build dir. I'm pointing out that Emacs has build artifacts being put outside build dir, hence the "out of tree build" workflow is not working as expected. > Building from Git is a special kind of activity; it has its > own INSTALL file and _must_ build some of the files in the source > tree. Are you aware of many projects whose build from Git can be > done > without first populating the source tree with some files? Most existing active projects 😊 Most that were using autotools/make has migrated to Meson. That includes active freedesktop projects (Mesa, Xorg, libinput, Pulseaudio, etc), Gnome projects, i3wm, Compton after it became Picom, all active Enlightenment projects… The list goes on and on. Meson drastically reduces maintainance burden but it's a separate story. What matters is that Meson by design works with out of tree builds. It is possible to hack in generating files in the tree, but it's frowned upon for many reasons. Then you have CMake projects, which I think has always supported out of tree build without creating any config files whatsoever outside? Offhand that includes all KDE projects. Lastly, you have autotools projects where `configure` file is not generated 😊 `fio` is one example (although admittedly I didn't test out of tree build in there, but clearly if you have `configure` as part of the codebase, then you don't have to generate it in the tree). > Heck, you > don't even have the configure script when you clone the repository, > and out-of-tree build works by invoking the configure script from a > directory _other_ than the one where the script lives. Right? Good point. That's yet another reason "out of tree build" workflow isn't fully supported. I just didn't think about it because didn't have problems with that, but you are correct here. > > The fact they're distributed in release tarballs does not make it > > less true. Distributing them in tarballs is not strictly > > necessary, > > exactly because they can be generated by anyone. > > Not true. Well, admittedly I didn't try building from release tarball. But if it lacks some code to re-create `.elc` files, that's a bug. I can explain why if you're interested. > > Having .elc files in the source tree results in problems when a > > user > > created a dir `build-feature1` for one feature branch, and a dir > > `build-feature2` for another; and then `build-feature1` somehow > > ends up > > having "feature2". Which is because it's using build artifacts > > that > > are outside `build-feature1`. > > Again, not relevant to the aspect on which I commented. Fair enough. I was just pointing out why "out of tree builds" should work the way they don't in Emacs right now. But yeah, if you already understand that, I guess my explanation on that is unnecessary. > > Thus, Emacs certainly does not fully support "out of tree" builds. > > It does. You are just talking about a very different kind of "out of > tree build". Well… There does not exist strict definition for "out of tree build" that I can point you to, so that risks becoming a philosophical debate. To understand what that means you need to understand what it solves. Which you seem to understand already per the previous paragraph, so I can only add that "partial out of tree build" still has problems that "full out of tree build" solves. So there is only one kind of "out of tree build", the "full" one. The "partial" one should be explicitly specified as being only partial, whereas saying "out of tree build" without any prefix implies it is a "full" one. I hope now you understand why I'm saying Emacs doesn't fully support it 😊 ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 15:00 ` Konstantin Kharlamov @ 2024-04-03 15:47 ` Eli Zaretskii 2024-04-03 17:27 ` Konstantin Kharlamov 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-03 15:47 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: rms, spacibba, dmitry, emacs-devel > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, emacs-devel@gnu.org > Date: Wed, 03 Apr 2024 18:00:28 +0300 > > I hope now you understand why I'm saying Emacs doesn't fully support it > 😊 I don't. I think you are plainly mistaken. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 15:47 ` Eli Zaretskii @ 2024-04-03 17:27 ` Konstantin Kharlamov 2024-04-03 18:22 ` Eli Zaretskii [not found] ` <87jzlefgi9.fsf@dick> 0 siblings, 2 replies; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-03 17:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rms, spacibba, dmitry, emacs-devel On Wed, 2024-04-03 at 18:47 +0300, Eli Zaretskii wrote: > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, > > emacs-devel@gnu.org > > Date: Wed, 03 Apr 2024 18:00:28 +0300 > > > > I hope now you understand why I'm saying Emacs doesn't fully > > support it > > 😊 > > I don't. I think you are plainly mistaken. Sure, that's a fair point, because if I consider something simple, that doesn't necessarily mean other people have the knowledge to think similarly. So to explain why I was saying that here's some points from my previous email that clarify that: The point of "out of tree build" is encapsulating build artifacts in the build dir. Emacs has some build artifacts outside build dir, hence the "out of tree build" workflow is not working as expected. To understand what "out of tree build" means you need to understand what it solves. Which you seem to understand already per prior discussion (but I may be mistaken here, just tell me if that's so), so let me just add that "partial out of tree build" still has problems that "full out of tree build" solves. So there is only one kind of "out of tree build", the "full" one. The "partial" one should be explicitly specified as such, whereas saying "out of tree build" without any prefix implies it is a "full" one. I hope now you understand why I'm saying Emacs doesn't fully support it 😊 ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 17:27 ` Konstantin Kharlamov @ 2024-04-03 18:22 ` Eli Zaretskii 2024-04-03 19:08 ` Konstantin Kharlamov [not found] ` <87jzlefgi9.fsf@dick> 1 sibling, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-03 18:22 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: rms, spacibba, dmitry, emacs-devel > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, emacs-devel@gnu.org > Date: Wed, 03 Apr 2024 20:27:09 +0300 > > I hope now you understand why I'm saying Emacs doesn't fully support it 😊 I still think you are mistaken. What you call "out of tree build" is not what is generally meant by that. Bootstrapping a repository invariably causes some "build artifacts" to be deposed in the source tree, and the more the project makes a point of not having generated files in the repository, the more artifacts are needed in the source tree before you can start building out of tree. And that is perfectly okay, nothing wrong about that. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 18:22 ` Eli Zaretskii @ 2024-04-03 19:08 ` Konstantin Kharlamov 2024-04-03 20:12 ` Ergus 2024-04-04 5:07 ` Eli Zaretskii 0 siblings, 2 replies; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-03 19:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rms, spacibba, dmitry, emacs-devel On Wed, 2024-04-03 at 21:22 +0300, Eli Zaretskii wrote: > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, > > emacs-devel@gnu.org > > Date: Wed, 03 Apr 2024 20:27:09 +0300 > > > > I hope now you understand why I'm saying Emacs doesn't fully > > support it 😊 > > I still think you are mistaken. What you call "out of tree build" is > not what is generally meant by that. Okay, what do you consider meant by that? > Bootstrapping a repository > invariably causes some "build artifacts" to be deposed in the source > tree Sure, that's unfortunately how autotools work. On the upside though, it is rare for these files to cause problems. Which can't be said about .elc ones. > , and the more the project makes a point of not having generated > files in the repository, the more artifacts are needed in the source > tree before you can start building out of tree. Citation needed 😄 You asked me previously for examples of projects that do not generate any files in the tree, I provided you with that 😊 I can certainly assure you that you don't necessarily have to generate files "in tree". I worked with many different projects and distinct build systems, so I have a lot of experience in that regard. Do you have in mind some specific case that you see a problem with? > And that is > perfectly okay, nothing wrong about that. There are problems with generating code in tree, some of which I did show to you previously. Unless I misunderstand what you mean by that. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 19:08 ` Konstantin Kharlamov @ 2024-04-03 20:12 ` Ergus 2024-04-04 5:26 ` Eli Zaretskii 2024-04-04 5:07 ` Eli Zaretskii 1 sibling, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-03 20:12 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: Eli Zaretskii, rms, dmitry, emacs-devel Hi Eli: I won't come into this discussion but: My basic concept of OOSC (probably mistaken) is that the sources of the project are those required to reproduce a program, because otherwise it is not possible or are too difficult/expensive to reproduce. If I change project.el, then project.elc is not valid anymore and needs to be regenerated... so, project.el is the source and the elc is a target (not necessarily a final one) In the same line, when we do out of sources compilation it may be possible to remove the `build` directory and have the project sources exactly as downloaded from sources. Without any other clean needed... Also in same line, for example, when using GIT_NAMESPACE the project.el will change with the namespace, but the elc won't (as not tracked by git), so GIT_NAMESPACE becomes inconsistent and requires a regeneration of .elc, so, not a source, but a target Finally when executing from build1 it may be possible to access the version of project.elc used when the project was compiled in that directory... independently of if I changed project.el latter and compiled in build2. Latter actions in source + compilation in build2 should not affect the consistency of build1. On Wed, Apr 03, 2024 at 10:08:16PM +0300, Konstantin Kharlamov wrote: >On Wed, 2024-04-03 at 21:22 +0300, Eli Zaretskii wrote: >> > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> >> > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, >> > emacs-devel@gnu.org >> > Date: Wed, 03 Apr 2024 20:27:09 +0300 >> > >> > I hope now you understand why I'm saying Emacs doesn't fully >> > support it 😊 >> >> I still think you are mistaken. What you call "out of tree build" is >> not what is generally meant by that. > >Okay, what do you consider meant by that? > >> Bootstrapping a repository >> invariably causes some "build artifacts" to be deposed in the source >> tree > >Sure, that's unfortunately how autotools work. On the upside though, >it is rare for these files to cause problems. Which can't be said >about .elc ones. > >> , and the more the project makes a point of not having generated >> files in the repository, the more artifacts are needed in the source >> tree before you can start building out of tree. > >Citation needed 😄 You asked me previously for examples of projects >that do not generate any files in the tree, I provided you with that 😊 >I can certainly assure you that you don't necessarily have to generate >files "in tree". I worked with many different projects and distinct >build systems, so I have a lot of experience in that regard. Do you >have in mind some specific case that you see a problem with? > >> And that is >> perfectly okay, nothing wrong about that. > >There are problems with generating code in tree, some of which I did >show to you previously. Unless I misunderstand what you mean by that. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 20:12 ` Ergus @ 2024-04-04 5:26 ` Eli Zaretskii 2024-04-04 9:59 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-04 5:26 UTC (permalink / raw) To: Ergus; +Cc: Hi-Angel, rms, dmitry, emacs-devel > Date: Wed, 3 Apr 2024 22:12:44 +0200 > From: Ergus <spacibba@aol.com> > Cc: Eli Zaretskii <eliz@gnu.org>, rms@gnu.org, dmitry@gutov.dev, > emacs-devel@gnu.org > > My basic concept of OOSC (probably mistaken) is that the sources of the > project are those required to reproduce a program, because otherwise it > is not possible or are too difficult/expensive to reproduce. > > If I change project.el, then project.elc is not valid anymore and needs > to be regenerated... so, project.el is the source and the elc is a > target (not necessarily a final one) The same is true for a change in configure.ac: the configure script is no longer valid after that, and needs to be rebuilt. > In the same line, when we do out of sources compilation it may be > possible to remove the `build` directory and have the project sources > exactly as downloaded from sources. Without any other clean > needed... That's not how the GNU build infrastructure works. You have the distclean target in Makefile to clean up the tree for the new build. > Also in same line, for example, when using GIT_NAMESPACE the project.el > will change with the namespace, but the elc won't (as not tracked by > git), so GIT_NAMESPACE becomes inconsistent and requires a regeneration > of .elc, so, not a source, but a target That is a problem with project.el, I think, not with how Emacs is built. In every project, when you bootstrap it, i.e. build from the VCS repository, there are some generated files that are part of the source tree. > Finally when executing from build1 it may be possible to access the > version of project.elc used when the project was compiled in that > directory... independently of if I changed project.el latter and > compiled in build2. Latter actions in source + compilation in build2 > should not affect the consistency of build1. You are talking about modifying project.el while it is being used by a running Emacs session? In that case, all bets are off, I think. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 5:26 ` Eli Zaretskii @ 2024-04-04 9:59 ` Ergus 2024-04-04 11:59 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-04 9:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Hi-Angel, rms, dmitry, emacs-devel Hi Eli On April 4, 2024 7:26:35 AM GMT+02:00, Eli Zaretskii <eliz@gnu.org> wrote: >> Date: Wed, 3 Apr 2024 22:12:44 +0200 >> From: Ergus <spacibba@aol.com> >> Cc: Eli Zaretskii <eliz@gnu.org>, rms@gnu.org, dmitry@gutov.dev, >> emacs-devel@gnu.org >> >> My basic concept of OOSC (probably mistaken) is that the sources of the >> project are those required to reproduce a program, because otherwise it >> is not possible or are too difficult/expensive to reproduce. >> >> If I change project.el, then project.elc is not valid anymore and needs >> to be regenerated... so, project.el is the source and the elc is a >> target (not necessarily a final one) > >The same is true for a change in configure.ac: the configure script is >no longer valid after that, and needs to be rebuilt. > And that's why the newer build systems generate the equivalent to the configure also out of sources. Or use the equivalent to configure.ac directly as input, generating everything out of sources. >> In the same line, when we do out of sources compilation it may be >> possible to remove the `build` directory and have the project sources >> exactly as downloaded from sources. Without any other clean >> needed... > >That's not how the GNU build infrastructure works. You have the >distclean target in Makefile to clean up the tree for the new build. > Makefile does not support oosc at all. Actually CMake generates the makefiles outside sources. >> Also in same line, for example, when using GIT_NAMESPACE the project.el >> will change with the namespace, but the elc won't (as not tracked by >> git), so GIT_NAMESPACE becomes inconsistent and requires a regeneration >> of .elc, so, not a source, but a target > >That is a problem with project.el, I think, not with how Emacs is >built. In every project, when you bootstrap it, i.e. build from the >VCS repository, there are some generated files that are part of the >source tree. > Indeed, CMake and actually most of newer autotools projects prefer to generate those files out of sources too. >> Finally when executing from build1 it may be possible to access the >> version of project.elc used when the project was compiled in that >> directory... independently of if I changed project.el latter and >> compiled in build2. Latter actions in source + compilation in build2 >> should not affect the consistency of build1. > >You are talking about modifying project.el while it is being used by a >running Emacs session? In that case, all bets are off, I think. No I mean having two emacs builds in different subdirectories. For example one compiled before certain change and the other after -- Sent from my Android device with K-9 Mail. Please excuse my brevity. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 9:59 ` Ergus @ 2024-04-04 11:59 ` Eli Zaretskii 2024-04-04 12:34 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-04 11:59 UTC (permalink / raw) To: Ergus; +Cc: Hi-Angel, rms, dmitry, emacs-devel > Date: Thu, 04 Apr 2024 11:59:29 +0200 > From: Ergus <spacibba@aol.com> > CC: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org > > >> Finally when executing from build1 it may be possible to access the > >> version of project.elc used when the project was compiled in that > >> directory... independently of if I changed project.el latter and > >> compiled in build2. Latter actions in source + compilation in build2 > >> should not affect the consistency of build1. > > > >You are talking about modifying project.el while it is being used by a > >running Emacs session? In that case, all bets are off, I think. > > No I mean having two emacs builds in different subdirectories. For example one compiled before certain change and the other after You are saying that Emacs can load project.elc from a wrong directory? Any reproducible recipe for that? ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 11:59 ` Eli Zaretskii @ 2024-04-04 12:34 ` Ergus 2024-04-04 13:02 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-04 12:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Hi-Angel, rms, dmitry, emacs-devel On Thu, Apr 04, 2024 at 02:59:27PM +0300, Eli Zaretskii wrote: >> Date: Thu, 04 Apr 2024 11:59:29 +0200 >> From: Ergus <spacibba@aol.com> >> CC: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org >> >> >> Finally when executing from build1 it may be possible to access the >> >> version of project.elc used when the project was compiled in that >> >> directory... independently of if I changed project.el latter and >> >> compiled in build2. Latter actions in source + compilation in build2 >> >> should not affect the consistency of build1. >> > >> >You are talking about modifying project.el while it is being used by a >> >running Emacs session? In that case, all bets are off, I think. >> >> No I mean having two emacs builds in different subdirectories. For example one compiled before certain change and the other after > >You are saying that Emacs can load project.elc from a wrong directory? >Any reproducible recipe for that? > No Eli: That's not what I mean. Ex: mkdir build1 && cd build1 && ../configure ... && make cd .. edit project.el mkdir build2 && cd build2 && ../configure ... && make cd .. build1/src/emacs -Q This will load the new elc, not the one used when it was compiled in spite of we have not recompiled in that build dir. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 12:34 ` Ergus @ 2024-04-04 13:02 ` Eli Zaretskii 2024-04-04 14:27 ` Ergus 0 siblings, 1 reply; 57+ messages in thread From: Eli Zaretskii @ 2024-04-04 13:02 UTC (permalink / raw) To: Ergus; +Cc: Hi-Angel, rms, dmitry, emacs-devel > Date: Thu, 4 Apr 2024 14:34:16 +0200 > From: Ergus <spacibba@aol.com> > Cc: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org > > On Thu, Apr 04, 2024 at 02:59:27PM +0300, Eli Zaretskii wrote: > > > >You are saying that Emacs can load project.elc from a wrong directory? > >Any reproducible recipe for that? > > > No Eli: > > That's not what I mean. Actually, yes, that's what you meant. > mkdir build1 && cd build1 && ../configure ... && make > cd .. > > edit project.el > mkdir build2 && cd build2 && ../configure ... && make > cd .. > > build1/src/emacs -Q > > This will load the new elc, not the one used when it was compiled in > spite of we have not recompiled in that build dir. AFAIU, it doesn't load the new project.elc from build2, it loads project.el (i.e. uncompiled Lisp) from the source tree, where you modified project.el. The reason is that Emacs's support for "running uininstalled" assumes the Lisp files are in the source tree. IOW, running uninstalled from a build directory outside of the source tree does not take the *.elc files from that build directory, as I think you can verify if you look at the value of load-path. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 13:02 ` Eli Zaretskii @ 2024-04-04 14:27 ` Ergus 2024-04-04 14:41 ` Eli Zaretskii 0 siblings, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-04 14:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Hi-Angel, rms, dmitry, emacs-devel On Thu, Apr 04, 2024 at 04:02:50PM +0300, Eli Zaretskii wrote: >> Date: Thu, 4 Apr 2024 14:34:16 +0200 >> From: Ergus <spacibba@aol.com> >> Cc: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org >> >> On Thu, Apr 04, 2024 at 02:59:27PM +0300, Eli Zaretskii wrote: >> > >> >You are saying that Emacs can load project.elc from a wrong directory? >> >Any reproducible recipe for that? >> > >> No Eli: >> >> That's not what I mean. > >Actually, yes, that's what you meant. > >> mkdir build1 && cd build1 && ../configure ... && make >> cd .. >> >> edit project.el >> mkdir build2 && cd build2 && ../configure ... && make >> cd .. >> >> build1/src/emacs -Q >> >> This will load the new elc, not the one used when it was compiled in >> spite of we have not recompiled in that build dir. > >AFAIU, it doesn't load the new project.elc from build2, it loads >project.el (i.e. uncompiled Lisp) from the source tree, where you >modified project.el. > >The reason is that Emacs's support for "running uininstalled" assumes >the Lisp files are in the source tree. IOW, running uninstalled from >a build directory outside of the source tree does not take the *.elc >files from that build directory, as I think you can verify if you look >at the value of load-path. Exactly, so this is not OOSC and does not behave as expected in OOSC. Which is what Konstantin pointed out since the beginning. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 14:27 ` Ergus @ 2024-04-04 14:41 ` Eli Zaretskii 2024-04-04 18:15 ` Ergus 2024-04-04 20:16 ` Konstantin Kharlamov 0 siblings, 2 replies; 57+ messages in thread From: Eli Zaretskii @ 2024-04-04 14:41 UTC (permalink / raw) To: Ergus; +Cc: Hi-Angel, rms, dmitry, emacs-devel > Date: Thu, 4 Apr 2024 16:27:34 +0200 > From: Ergus <spacibba@aol.com> > Cc: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org > > >The reason is that Emacs's support for "running uininstalled" assumes > >the Lisp files are in the source tree. IOW, running uninstalled from > >a build directory outside of the source tree does not take the *.elc > >files from that build directory, as I think you can verify if you look > >at the value of load-path. > > Exactly, so this is not OOSC and does not behave as expected in > OOSC. No, it isn't. Not many programs at all support running uninstalled. Emacs does, but only if you build inside the source. This is unrelated to the possibility of out-of-source build, where you are supposed to say "make install" after you build. > Which is what Konstantin pointed out since the beginning. No, he didn't. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 14:41 ` Eli Zaretskii @ 2024-04-04 18:15 ` Ergus 2024-04-04 18:56 ` Eli Zaretskii 2024-04-04 20:16 ` Konstantin Kharlamov 1 sibling, 1 reply; 57+ messages in thread From: Ergus @ 2024-04-04 18:15 UTC (permalink / raw) To: emacs-devel, Eli Zaretskii; +Cc: Hi-Angel, rms, dmitry On April 4, 2024 4:41:58 PM GMT+02:00, Eli Zaretskii <eliz@gnu.org> wrote: >> Date: Thu, 4 Apr 2024 16:27:34 +0200 >> From: Ergus <spacibba@aol.com> >> Cc: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org >> >> >The reason is that Emacs's support for "running uininstalled" assumes >> >the Lisp files are in the source tree. IOW, running uninstalled from >> >a build directory outside of the source tree does not take the *.elc >> >files from that build directory, as I think you can verify if you look >> >at the value of load-path. >> >> Exactly, so this is not OOSC and does not behave as expected in >> OOSC. > >No, it isn't. Not many programs at all support running uninstalled. All CMake and Meson programs do it by default. Mainly because they also provide test features where the executables are supposed to be tested before calling install or pack. >Emacs does, but only if you build inside the source. This is >unrelated to the possibility of out-of-source build, where you are >supposed to say "make install" after you build. > >> Which is what Konstantin pointed out since the beginning. > >No, he didn't. > -- Sent from my Android device with K-9 Mail. Please excuse my brevity. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 18:15 ` Ergus @ 2024-04-04 18:56 ` Eli Zaretskii 0 siblings, 0 replies; 57+ messages in thread From: Eli Zaretskii @ 2024-04-04 18:56 UTC (permalink / raw) To: Ergus; +Cc: emacs-devel, Hi-Angel, rms, dmitry > Date: Thu, 04 Apr 2024 20:15:56 +0200 > From: Ergus <spacibba@aol.com> > CC: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev > > >> Exactly, so this is not OOSC and does not behave as expected in > >> OOSC. > > > >No, it isn't. Not many programs at all support running uninstalled. > > All CMake and Meson programs do it by default. Mainly because they also provide test features where the executables are supposed to be tested before calling install or pack. I don't see how CMake or Meson can make a program run uninstalled, unless the program already provides the necessary features for doing so. Imagine a program that needs to read some data files, which it expects to find in a directory under /usr/share whose absolute file name is hard-coded into it, as determined from --prefix at configure time. Such a program cannot run uninstalled, because the files in /usr/share are not yet installed. Emacs needs to know where to find the Lisp files it loads on demand. If those files are in the place configured via --prefix, they can be found easily, but if Emacs runs uninstalled, the Lisp files are not there, and Emacs needs to find them somehow. Unless someone writes code to look for them in the right places, there's no way CMake or Meson or any other general-purpose tool could fix that. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 14:41 ` Eli Zaretskii 2024-04-04 18:15 ` Ergus @ 2024-04-04 20:16 ` Konstantin Kharlamov 2024-04-05 5:11 ` Eli Zaretskii 1 sibling, 1 reply; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-04 20:16 UTC (permalink / raw) To: Eli Zaretskii, Ergus; +Cc: rms, dmitry, emacs-devel On Thu, 2024-04-04 at 17:41 +0300, Eli Zaretskii wrote: > > Date: Thu, 4 Apr 2024 16:27:34 +0200 > > From: Ergus <spacibba@aol.com> > > Cc: Hi-Angel@yandex.ru, rms@gnu.org, dmitry@gutov.dev, > > emacs-devel@gnu.org > > > > > The reason is that Emacs's support for "running uininstalled" > > > assumes > > > the Lisp files are in the source tree. IOW, running uninstalled > > > from > > > a build directory outside of the source tree does not take the > > > *.elc > > > files from that build directory, as I think you can verify if you > > > look > > > at the value of load-path. > > > > Exactly, so this is not OOSC and does not behave as expected in > > OOSC. > > No, it isn't. Not many programs at all support running uninstalled. > Emacs does, but only if you build inside the source. This is > unrelated to the possibility of out-of-source build, where you are > supposed to say "make install" after you build. Indeed running uninstalled is kind of orthogonal to OOSC and may or may not be supported by a program. I think this discussion might be confusing two orthogonal things: α) `.elc` files being put in-tree, and β) Emacs requiring for them to be put in-tree to run "uninstalled". For β: I'm sure it's possible to modify Emacs to load `.elc` from the build dir rather than from the tree. For α: the lone fact that build artifacts are being put in-tree means OOSC is not working as expected. I see what you mean by saying that `configure` and similar files can't be put into the build dir because that's how autotools work. Okay. But I think this whole discussion about the terminology is becoming not very useful. Can we please agree that generating .elc files in the build dir rather than in tree allows to avoid a number of problems? Please note that this has nothing to do with `.elc` files being put in tarballs, because for that to work you could just build "in-tree" as usual. Putting `.elc` files into build dir (which may be in-tree or out) and allowing Emacs to take those into account is just simplification in how things work. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-04 20:16 ` Konstantin Kharlamov @ 2024-04-05 5:11 ` Eli Zaretskii 0 siblings, 0 replies; 57+ messages in thread From: Eli Zaretskii @ 2024-04-05 5:11 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: spacibba, rms, dmitry, emacs-devel > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > Cc: rms@gnu.org, dmitry@gutov.dev, emacs-devel@gnu.org > Date: Thu, 04 Apr 2024 23:16:29 +0300 > > Can we please agree that generating .elc files in the > build dir rather than in tree allows to avoid a number of problems? > Please note that this has nothing to do with `.elc` files being put in > tarballs, because for that to work you could just build "in-tree" as > usual. Putting `.elc` files into build dir (which may be in-tree or > out) and allowing Emacs to take those into account is just > simplification in how things work. As I wrote up-thread, I have no objections for adding this to Emacs, but it is not as trivial as it seems, because Emacs needs more files than just *.elc to run, and some of those other files are in the source tree when Emacs runs uninstalled (example: the images in etc/images). So adding this mode of running Emacs would need some changes to the C startup code, not just to Makefile's. Also, if you edit *.el files in the source directory, the *.eln files produced from the *.el files before the edits will no longer be loaded by Emacs (because they don't match the corresponding *.el files); if we want to fix that as well, we'd need much more serious changes. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH] Project out of sources compilation 2024-04-03 19:08 ` Konstantin Kharlamov 2024-04-03 20:12 ` Ergus @ 2024-04-04 5:07 ` Eli Zaretskii 1 sibling, 0 replies; 57+ messages in thread From: Eli Zaretskii @ 2024-04-04 5:07 UTC (permalink / raw) To: Konstantin Kharlamov; +Cc: rms, spacibba, dmitry, emacs-devel > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, emacs-devel@gnu.org > Date: Wed, 03 Apr 2024 22:08:16 +0300 > > On Wed, 2024-04-03 at 21:22 +0300, Eli Zaretskii wrote: > > > From: Konstantin Kharlamov <Hi-Angel@yandex.ru> > > > Cc: rms@gnu.org, spacibba@aol.com, dmitry@gutov.dev, > > > emacs-devel@gnu.org > > > Date: Wed, 03 Apr 2024 20:27:09 +0300 > > > > > > I hope now you understand why I'm saying Emacs doesn't fully > > > support it 😊 > > > > I still think you are mistaken. What you call "out of tree build" is > > not what is generally meant by that. > > Okay, what do you consider meant by that? In general, a build outside of the tree where a release tarball has been unpacked. At the very least, a build _after_ autogen.sh (or a similar "bootstrap" script) was run. Note that the rules which produce *.elc files do deposit them in the build tree, not in the source tree, btw. AFAIR, the only Lisp files produced by a build from Git that are deposited in the source tree are those built by admin/grammars/Makefile. If someone wants to modify that Makefile to produce the *.el files in the build tree, I won't object, but rejecting the Emacs out-of-tree build procedure because we currently put them in the source tree is absurd, IMNSHO, since *.el files are certainly portable and not configuration- or platform-dependent. Putting platform-independent generated files in the source tree has the advantage of making the subsequent builds faster, sometimes significantly faster. > > Bootstrapping a repository > > invariably causes some "build artifacts" to be deposed in the source > > tree > > Sure, that's unfortunately how autotools work. See above: not just autotools. And anyway, as long as the Emacs build uses autotools, we can only support out-of-tree builds in the style supported by autotools. > On the upside though, it is rare for these files to cause problems. > Which can't be said about .elc ones. See above: the *.elc files are not relevant here. > > , and the more the project makes a point of not having generated > > files in the repository, the more artifacts are needed in the source > > tree before you can start building out of tree. > > Citation needed 😄 You asked me previously for examples of projects > that do not generate any files in the tree, I provided you with that 😊 > I can certainly assure you that you don't necessarily have to generate > files "in tree". I worked with many different projects and distinct > build systems, so I have a lot of experience in that regard. Do you > have in mind some specific case that you see a problem with? Yes, look at Gawk, for example: they have many generated files in Git. Even Info files are in Git. Another example is GDB: they store the configure script in Git. > > And that is > > perfectly okay, nothing wrong about that. > > There are problems with generating code in tree, some of which I did > show to you previously. There are problems everywhere, but those are quite easy to deal with. Otherwise you wouldn't be seeing projects doing that, and doing that on purpose. ^ permalink raw reply [flat|nested] 57+ messages in thread
[parent not found: <87jzlefgi9.fsf@dick>]
* Re: [PATCH] Project out of sources compilation [not found] ` <87jzlefgi9.fsf@dick> @ 2024-04-03 18:44 ` Konstantin Kharlamov 0 siblings, 0 replies; 57+ messages in thread From: Konstantin Kharlamov @ 2024-04-03 18:44 UTC (permalink / raw) To: dick; +Cc: Eli Zaretskii, rms, spacibba, dmitry, emacs-devel Wow. Please, offense is unwelcome. Eli is a great man who maintains the project and writes code. Other people come and go, Eli stays. I'm very thankful to him for doing that job. Disagreement happens, that's okay. No need to call names. ^ permalink raw reply [flat|nested] 57+ messages in thread
end of thread, other threads:[~2024-04-26 0:47 UTC | newest] Thread overview: 57+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <4wwljrdnra3bsloehioa46y24ozxajajmvf2elvskxxq3mhtg2.ref@pyv2z5snot6h> 2024-03-16 13:12 ` Project out of sources compilation Ergus 2024-03-16 16:50 ` Konstantin Kharlamov 2024-03-16 19:00 ` Ergus 2024-03-16 20:56 ` Konstantin Kharlamov 2024-03-17 2:53 ` Dmitry Gutov 2024-03-17 7:22 ` Ergus 2024-03-17 8:45 ` Eli Zaretskii 2024-03-17 17:33 ` Ergus 2024-03-17 17:38 ` Eli Zaretskii 2024-03-17 17:58 ` Ergus 2024-03-17 11:36 ` Augusto Stoffel 2024-03-17 17:47 ` Ergus 2024-03-19 18:36 ` Ergus 2024-03-27 16:38 ` [PATCH] " Ergus 2024-03-31 2:41 ` Dmitry Gutov 2024-03-31 21:07 ` Ergus 2024-04-01 7:49 ` Dirk-Jan C. Binnema 2024-04-01 13:52 ` Ergus 2024-04-01 15:09 ` Dirk-Jan C. Binnema 2024-04-01 17:18 ` Ergus 2024-04-02 23:23 ` Dmitry Gutov 2024-04-03 19:47 ` Ergus 2024-04-06 2:05 ` Ergus 2024-04-14 1:44 ` Dmitry Gutov 2024-04-16 14:56 ` Ergus 2024-04-22 17:05 ` Ergus 2024-04-22 18:48 ` Ergus 2024-04-22 21:20 ` Mohsin Kaleem 2024-04-23 15:17 ` Ergus 2024-04-23 19:26 ` Mohsin Kaleem 2024-04-26 0:47 ` Dmitry Gutov 2024-04-02 21:39 ` Richard Stallman 2024-04-02 22:43 ` Dr. Arne Babenhauserheide 2024-04-05 21:40 ` Richard Stallman 2024-04-03 10:40 ` Konstantin Kharlamov 2024-04-03 11:45 ` Eli Zaretskii 2024-04-03 13:31 ` Konstantin Kharlamov 2024-04-03 14:11 ` Eli Zaretskii 2024-04-03 15:00 ` Konstantin Kharlamov 2024-04-03 15:47 ` Eli Zaretskii 2024-04-03 17:27 ` Konstantin Kharlamov 2024-04-03 18:22 ` Eli Zaretskii 2024-04-03 19:08 ` Konstantin Kharlamov 2024-04-03 20:12 ` Ergus 2024-04-04 5:26 ` Eli Zaretskii 2024-04-04 9:59 ` Ergus 2024-04-04 11:59 ` Eli Zaretskii 2024-04-04 12:34 ` Ergus 2024-04-04 13:02 ` Eli Zaretskii 2024-04-04 14:27 ` Ergus 2024-04-04 14:41 ` Eli Zaretskii 2024-04-04 18:15 ` Ergus 2024-04-04 18:56 ` Eli Zaretskii 2024-04-04 20:16 ` Konstantin Kharlamov 2024-04-05 5:11 ` Eli Zaretskii 2024-04-04 5:07 ` Eli Zaretskii [not found] ` <87jzlefgi9.fsf@dick> 2024-04-03 18:44 ` Konstantin Kharlamov
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).