2012-01-27 97 views
15

我在Emacs下編碼OCaml,在工作文件夾中有一個makefile,以及幾個包含.ml文件的子文件夾。如果我啓動M-x compilemake正常工作的上一個makefile緩衝,但在一個.ml文件的緩衝區是不行的,它給了我一個錯誤:如何在Emacs中設置編譯的默認目錄?

-*- mode: compilation; default-directory: "..." -*- 
Compilation started at Fri Jan 27 18:51:35 

make -k 
make: *** No targets specified and no makefile found. Stop. 

Compilation exited abnormally with code 2 at Fri Jan 27 18:51:35 

這是可以理解的,因爲默認的目錄是子不包含makefile的文件夾。有誰知道如何將makefile的文件夾始終設置爲編譯的默認目錄?

回答

1

馬蒂亞斯PUECH都有一個solution涉及.dir-local文件在項目的根目錄:

((nil . ((eval . (setq default-directory 
        (locate-dominating-file buffer-file-name 
        ".dir-locals.el") 
))))) 

這大概也可以使用類似於:(shell-command-to-string "git rev-parse --show-toplevel")作爲最裏面的位。

+0

不不不不不不:no這樣會破壞一切,包括'find-file'。 – 2016-03-24 19:30:29

15

可以調用make用正確的參數:

make -C .. -k 

其中..是路徑到您的Makefile

+0

[whoa](http://i.memeful.com/media/post/PM0aaRL_700wa_0.gif) – vagoberto 2017-05-31 16:16:24

+0

哈,正在四處尋找這個問題,而你的回答是事後最明顯的一個,我更喜歡它在_define-your-own-custom-function-with-a-hook-and-change-it-you-need-a-different-path_上面回答。謝謝! – agam 2018-03-01 00:17:37

4

我用這樣的腳本,讓我從運行任何子目錄使(假設你處於類似posix的環境)。只是把這個腳本在PATH爲類似「sub_make.sh」並調用它,你將調用做出同樣的方式:通過編寫一個(暫時)設置default-directory功能

#!/bin/bash 

# search for project base 
INIT_DIR=`pwd` 
while [ "$PWD" != "/" ] ; do 
    if [ -e "makefile" ] ; then 
    break 
    fi 

    cd .. 
done 

if [ ! -e "makefile" ] ; then 
    echo "Couldn't find 'makefile'!" 
    exit 1 
fi 

# indicate where we are now 
echo "cd "`pwd` 
echo make "[email protected]" 

# now run make for real 
exec make "[email protected]" 
+1

你可以修改如下:'if [-e「makefile」] || [-e「Makefile」] || [-e「GNUmakefile」];然後'允許標準的makefile名稱 – 2013-03-09 17:32:07

8

您可以從emacs的內控制這種並致電compile

(defun compile-in-parent-directory() 
    (interactive) 
    (let ((default-directory 
      (if (string= (file-name-extension buffer-file-name) "ml") 
       (concat default-directory "..") 
      default-directory)))) 
    (call-interactively #'compile)) 

當使用compile-in-parent-directory所有ml文件將在他們在哪裏父目錄進行編譯。當然,如果他們嵌套得更深,你可以改變邏輯來反映這一點。實際上有一個version on the EmacsWiki,它搜索父目錄,直到找到一個makefile。在我寫這個答案後我發現了這個,否則我會在那裏指出你的。 感嘆。關於我的方法的好處是,它不是特定於make,因此您可以對其他命令使用相同的「技巧」。

如果您確切知道您想要的命令是什麼,那麼您也可以將調用編譯爲非交互式。如果它在適當的模式鉤子中綁定到一個鍵,這將特別有效。

+0

感謝您的回答......我已將您的代碼添加到'。emacs',但在'Mx'之後,它找不到'compile-in-parent-directory' – SoftTimur 2012-01-31 14:02:32

+0

我已經把EmacsWiki上的代碼改爲'.emacs',按'F5'給我一個錯誤:'Symbol的函數定義是void:loop'。 – SoftTimur 2012-01-31 14:11:03

+0

要使功能可用於與M-x的交互呼叫,您必須將(交互式)作爲第一條語句添加到您的功能中。 – 2012-01-31 14:27:39

4

這就是我在我的一些CONFIGS :)

(defun* get-closest-pathname (&optional (max-level 3) (file "Makefile")) 
    (let* ((root (expand-file-name "/")) 
     (level 0) 
     (dir (loop 
       for d = default-directory then (expand-file-name ".." d) 
       do (setq level (+ level 1)) 
       if (file-exists-p (expand-file-name file d)) 
       return d 
       if (> level max-level) 
       return nil 
       if (equal d root) 
       return nil))) 
    (if dir 
     (expand-file-name file dir) 
     nil))) 

(add-hook 'c-mode-hook 
      (lambda() 
      (unless (file-exists-p "Makefile") 
       (set (make-local-variable 'compile-command) 
        (let ((file (file-name-nondirectory buffer-file-name)) 
         (mkfile (get-closest-pathname))) 
        (if mkfile 
         (progn (format "cd %s; make -f %s" 
          (file-name-directory mkfile) mkfile)) 
         (format "%s -c -o %s.o %s %s %s" 
           (or (getenv "CC") "gcc") 
           (file-name-sans-extension file) 
           (or (getenv "CPPFLAGS") "-DDEBUG=9") 
           (or (getenv "CFLAGS") "-ansi -pedantic -Wall -g") 
           file))))))) 
+0

感謝您的回答......我已將您的代碼添加到'.emacs'中,但啓動emacs後,它會給我一個警告:Warning(initialization):加載'〜/ .emacs'時發生錯誤:Symbol的函數定義無效:defun *' – SoftTimur 2012-01-31 14:05:06

+2

hm ...嘗試在此功能之前添加(需要'cl')。 – 2012-01-31 14:23:33

+0

謝謝Bad_ptr。我用你的代碼有一個命令,可以在任何模式下執行主目錄中的make命令,而不僅僅是C,如果緩衝區處於目錄模式。 我希望它不做任何事情,但如果它沒有找到Makefile的主目錄。不幸的是我的功能仍然執行make。你能建議嗎? (全球設置鍵[F1] \t \t(拉姆達() \t \t(互動) \t \t(編譯 (讓((mkfile(GET-最接近-路徑名))) \t \t(如果mkfile \t \t(格式爲 「CD%S;使」 \t \t \t \t(文件名,目錄(GET-最接近-路徑名)))) \t \t \t \t)))) – SFbay007 2013-08-14 18:11:21

相關問題