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.