現在我用下面來編譯,當我在例如main.cpp中使用Emacs,是否可以將編譯命令固定到特定的緩衝區/目錄?
C-x b Makefile RET M-x compile RET RET
其實,我的Mx編譯爲鍵盤快捷鍵,但問題是我真的想不不得不經歷所有這些麻煩來簡單地運行我的Makefile。
我需要訪問Makefile以確保編譯命令使用相同的目錄執行。有沒有什麼方法來固定目錄,所以我可以簡單地去M-x compile RET RET
?
問候
現在我用下面來編譯,當我在例如main.cpp中使用Emacs,是否可以將編譯命令固定到特定的緩衝區/目錄?
C-x b Makefile RET M-x compile RET RET
其實,我的Mx編譯爲鍵盤快捷鍵,但問題是我真的想不不得不經歷所有這些麻煩來簡單地運行我的Makefile。
我需要訪問Makefile以確保編譯命令使用相同的目錄執行。有沒有什麼方法來固定目錄,所以我可以簡單地去M-x compile RET RET
?
問候
使用recompile
來代替。 C-u M-x recompile
會讓你先編譯編譯命令。無論哪種方式編譯將工作在最後編譯完成的目錄。
我主要在Windows上運行emacs。
當我有一個makefile是在C模塊的父目錄,我用這個作爲編譯命令:
CD .. & & NMAKE <參數這裏>
例如:
CD .. & & NMAKE CONFIG =調試PLATFORM = 64目標
除此之外,我發現指定我想要爲各種模塊運行make命令行是一種痛苦。我想要一種方法將默認編譯命令附加到正在編輯的緩衝區。所以我寫了一個小小的elisp來處理這個工作。我想插入到每個頭註釋緩衝線,將規定我的優選的編譯命令,像這樣:
編譯:CD .. & & NMAKE CONFIG =調試PLATFORM = 64目標
然後有一段elisp運行,在我調用M-x compile
之前抓住這條線並將其作爲我想要運行的編譯命令提出。
這defun定義拉一條線出來的頭註釋:
(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's 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))))))))
好了,現在我需要的東西來調用之前我調用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))
然後當然,猜測編譯命令的defun定義:
(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 "))))
最終位是結合C-x C-e
,通常結合於compile
,到包裝defun定義:
(global-set-key "\C-x\C-e" 'cheeso-invoke-compile-interactively)
現在,當我在緩衝區中執行C-x C-e
時,它搜索編譯命令,並向我提供它找到的命令。我可以編輯建議的編譯命令,然後按ENTER鍵並運行它。
見我的回答here
目錄局部變量提供了一種簡單的方法來從一個子目錄中的任何源文件的父目錄觸發編譯。
我不明白;你是否說.cpp文件與Makefile不在同一個目錄中?這是問題嗎? – Cheeso
@Cheeso那麼不是*問題*。我會說,在不同的目錄中有.cpp文件是非常明智的。問題是emacs使用當前緩衝區目錄並在那裏運行編譯命令... – Max