Using Emacs, is it possible to associate a compilation command with a specific buffer / directory?

Now I use the following to compile when I am in the main.cpp file

Cx b Makefile RET Mx compile RET RET

I actually have a compilation of Mx as a keyboard shortcut, but the problem is that I really would not want to go through all these problems just to run my Makefile.

I need to visit the Makefile to make sure that the compilation command is executed using the same directory. Is there a way to link the directory so that I can just go Mx compile RET RET ?

Best wishes

+4
source share
3 answers

Use recompile instead. Cu Mx recompile allows you to edit the compilation command first. In any case, compilation will work from the directory in which the last compiler was executed.

+4
source

See my answer here

Local directory variables provide an easy way to start compilation from the parent directory of any source file in a subdirectory.

+2
source

I run emacs primarily on windows.
When I have a makefile that is in the parent directory of the C module, I use it as a compilation command:

cd .. && nmake <arguments here>

eg:

cd .. && nmake CONFIG = Debug PLATFORM = x64 target

In addition, I believe that specifying the make command line that I want to run for different modules is a pain. I wanted to associate the default compilation command with an editable buffer. So I wrote some help to handle this work. I decided to insert a line in the header comments of each buffer that would provide for my preferred compilation command, for example:

compile: cd .. && & nmake CONFIG = Debug PLATFORM = x64 target

And then run the elisp snippet before I call Mx compile , which captures the line and offers it as a compilation command that I would like to run.

This defun pulls a line from the header comments:

 (defun cheeso-c-get-value-from-comments (marker-string line-limit) "gets a string from the header comments in the current buffer. This is used to extract the compile command from the comments. It could be used for other purposes too. It looks for \"marker-string:\" and returns the string that follows it, or returns nil if that string is not found. eg, when marker-string is \"compile\", and the following string is found at the top of the buffer: compile: cl.exe /I uthash ...then this command will return the string \"cl.exe /I uthash\" It ok to have whitespace between the marker and the following colon. " (let (start search-limit found) ;; determine what lines to look in (save-excursion (save-restriction (widen) (cond ((> line-limit 0) (goto-char (setq start (point-min))) (forward-line line-limit) (setq search-limit (point))) ((< line-limit 0) (goto-char (setq search-limit (point-max))) (forward-line line-limit) (setq start (point))) (t ;0 => no limit (use with care!) (setq start (point-min)) (setq search-limit (point-max)))))) ;; look in those lines (save-excursion (save-restriction (widen) (let ((re-string (concat "\\b" marker-string "[ \t]*:[ \t]*\\(.+\\)$"))) (if (and start (< (goto-char start) search-limit) (re-search-forward re-string search-limit 'move)) (buffer-substring-no-properties (match-beginning 1) (match-end 1)))))))) 

Ok, now I need to call something before I call compile .

 (defun cheeso-invoke-compile-interactively () "fn to wrap the `compile' function. This simply checks to see if `compile-command' has been previously set, and if not, invokes `cheeso-guess-compile-command' to set the value. Then it invokes the `compile' function, interactively." (interactive) (cond ((not (boundp 'cheeso-local-compile-command-has-been-set)) (cheeso-guess-compile-command) (set (make-local-variable 'cheeso-local-compile-command-has-been-set) t))) ;; local compile command has now been set (call-interactively 'compile)) 

Then, of course, defun, which guesses the compilation command:

 (defun cheeso-guess-compile-command () "set `compile-command' intelligently depending on the current buffer, or the contents of the current directory." (interactive) (set (make-local-variable 'compile-command) (cond (buffer-file-name (let ((filename (file-name-nondirectory buffer-file-name))) (cond ;; editing a C-language source file - check for an ;; explicitly-specified command ((string-equal (substring buffer-file-name -2) ".c") (let ((explicit-compile-command (cheeso-c-get-value-from-comments "compile" 34))) (or explicit-compile-command (concat "nmake " ;; assume a makefile exists (file-name-sans-extension filename) ".exe")))) ;; editing a makefile - just run nmake ((string-equal (substring buffer-file-name -8) "makefile") "nmake ") ;; something else - do a typical .exe build (t (concat "nmake " (file-name-sans-extension filename) ".exe"))))) (t ;; punt "nmake ")))) 

The final bit should bind Cx Ce , usually associated with compile , with the defun wrapper:

 (global-set-key "\Cx\Ce" 'cheeso-invoke-compile-interactively) 

Now, when I do Cx Ce in the buffer, it looks for the compilation command and offers me the command that it finds. I can edit the suggested compilation command, then press ENTER and run it.

+1
source

All Articles