2009-11-03 28 views
5

Tengo un archivo MAKE en el directorio raíz del proyecto. Si estoy editando un archivo en un subdirectorio, ¿cómo invoco para hacer de EMACS? M-x compile make no funcionará como busca el archivo MAKE en el directorio actual. Pero tengo el archivo MAKE en el directorio raíz del proyecto.Invocando el archivo MAKE en el directorio raíz del proyecto desde el subdirectorio de Emacs

¿Alguna idea?

Editar

Como se sugirió, make -f fullpath_to_makefile hizo el truco. Pero tengo algunos incluye en el archivo MAKE como incluir "tests/module.mk" que falló. Está buscando el directorio "tests" en el subdirectorio. Esto se puede resolver especificando la ruta completa en el archivo MAKE. Pero no creo que sea una buena solución. Cualquier mejor enfoque?

Respuesta

5

La función M-x compile busca el compile-command-variable la que se puede reemplazar en el promt - por lo que sólo reemplazarlo con algo como

(cd ../.. && make && cd -) 

y dejar que se ejecutan.

también suelen utilizar un encabezado de archivo (en la línea 1), tales como

// -*- compile-command: "g++ -o myprog myprog.ccc -lfoo -lbar && ./myprog"; -*- 

que se puede generalizar a voluntad con diferentes opciones. Después de volver a cargar el archivo, M-x compile ejecutará su comando de compilación personalizado que me parece bastante útil.

+0

Genial. Hice que esto funcione. Se agregó "(setq compile-command" (cd ~/fullpath_to_project_root/&& make && cd -) ")" en el archivo .emacs. Parece que podría necesitar probar EDE y establecer comandos específicos del proyecto. Pero esto es suficiente por ahora. Gracias de nuevo. –

+0

En realidad, prefiero compilar-comando en cada archivo fuente. De esta forma se configuran cuando se cargan, perfecto en un directorio como ~/cpp/misc/donde puedo necesitar Boost para archivos de prueba, Qt para otros, etc. pp. Pero si siempre necesita el mismo comando de compilación, el ~/.emacs es válido también –

1

Cuando uso Emacs para compilar el minibúffer se ve algo así;

make -k

y acabo de añadir cualquier texto que me gusta, como -f ../../root/Makefile. Esto podría funcionar para ti.

Marcos

+0

El modificador -f hizo el truco. Pero en el archivo MAKE, tengo algunos incluyen como "include tests/module.mk" y se queja de que no puede encontrar el directorio "tests". Está buscando "pruebas" en el subdirectorio. Parece que necesito usar una ruta totalmente calificada en todas partes. Gracias por la respuesta. –

1

No soy mucho de un usuario de Emacs, pero podría pasar make -C ../ o sin embargo muchos directorios hasta que tienes que ir?

+0

Esto ejecutará make en el directorio raíz. Appu quiere ejecutar make en el directorio local, utilizando el archivo MAKE en el directorio raíz. – Beta

+0

Sospecho que eso no es lo que Appu realmente quiere, ya que un Makefile que solo funciona cuando * no * se ejecuta desde su propio directorio está en el límite de la locura. Esta es la técnica adecuada para ejecutar makefiles desde "otro lado". –

+0

1) Nadie (antes que usted) ha sugerido un Makefile que solo funciona cuando * no * se ejecuta desde su propio directorio. 2) Esta no es la forma de ejecutar Makefiles desde otro lado-- PRUÉBALO. – Beta

2

Uso EDE (de CEDET) para definir proyectos y almacenar comandos de compilación en la definición del proyecto. Consulte my config para ejemplos: líneas 105-133 - ejemplos de proyectos, líneas 135-165 - código, que define funciones de compilación, y líneas 168-189 - funciones para diferentes tipos de proyectos - estándar (compilación desde el directorio raíz), y cmake (compilación de directorio separado)

+0

Gracias. Desafortunadamente, EDE no está funcionando en mi extremo. No puedo ver el menú del proyecto. Ya he seguido tu artículo pero no ayudó para EDE. –

0

Esto debe hacerlo:

 
make -f path_to_rootdir/Makefile -I path_to_rootdir/tests 

el -f le dice qué makefile de usar, el -I lo dice dónde buscar los archivos que se incluirán en el archivo MAKE (que no están en el directorio local).

+0

Esto puede funcionar, pero cualquier herramienta que ejecute make tendrá su directorio de trabajo en un lugar diferente de lo esperado. La técnica adecuada es la opción -C, como se detalla a continuación. O poner un comando de cd en el comando de compilación M-x, como lo explica Dirk arriba. –

+0

Usted está equivocado, Sr. Ross, en los tres puntos. – Beta

+0

Argumento sin pruebas. Solo revisa la página de manual si no me crees; el argumento -f especifica el archivo MAKE, no cambia el directorio de trabajo. La opción -I es un truco para sortear ese problema para ** hacerse a sí mismo **, pero no para ninguno de los procesos que genera. Si tienen alguna dependencia de cwd (la mayoría lo hace), no funcionarán correctamente. –

0

Comience con M-x compile RET. Cuando solicite un comando, simplemente ingrese cd /path/to/root && make y presione regresar. Este comando funciona para todas las variantes de make y maneja el problema de "archivo incluido" sin ningún indicador adicional.

La próxima vez que escriba M-x compile RET, esta nueva cadena se presentará como la predeterminada, por lo que solo tendrá que presionar return. En el caso de que esté compilando activamente proyectos múltiples dentro de emacs, puede usar M-p y M-n para avanzar y retroceder en el historial de compilación de comandos.

+0

Gracias. Lo he agregado al archivo de inicialización de emacs y todo funciona ahora. –

+0

Mi punto es que no necesita hacer ninguna personalización .emacs. Sin embargo, hay múltiples soluciones para cada problema de emacs, así que si has encontrado algo que funcione, eso es suficiente. –

1

Después de un tiempo de diferentes intentos para hacer EDE funcione de la manera que quería, fui por .dir-locals.el:

((c++-mode . ((compile-command . "make -C ../build -j2 whatever"))))

me pareció un poco mejor para mí que tener un // -*- -*- en una cabecera de cada archivo, y mucho mejor que en mi especificando init.el (o cualquier otra configuración) los ede-cpp-root-project con rutas completas a proyectos, que yo tampoco crean demasiada frecuencia o mover de repente :)

Una buena adición al esquema fue cmake, lo que hace que los errores de compilación sean "jumpables correctamente", ya que utiliza rutas completas en los archivos make generados.

3

(utilizo scons, pero el principio es el mismo. Cambie SConstruct a Makefile y scons para hacer ...)

He personalizado por .emacs de modo que siempre se compila el proyecto que contiene del búfer archivo, sin embargo profundamente anidado; busca hacia arriba el primer SConstruct y lo usa como su directorio raíz de proyecto.

Aquí hay un par de funciones que buscan en la jerarquía de directorios en busca de SConstruct.

;; inspired by jds-find-tags-file in http://www.emacswiki.org/emacs/EmacsTags 
(defun find-sconstruct() 
"recursively searches upwards from buffer's current dir for file named SConstruct and returns that dir. Or nil if not found or if buffer is not visiting a file" 
    (labels 
     ((find-sconstruct-r (path) 
          (let* ((parent (file-name-directory path))  
           (possible-file (concat parent "SConstruct"))) 
          (cond 
          ((file-exists-p possible-file) 
           (throw 'found-it possible-file)) 
          ((string= "/SConstruct" possible-file) 
           (error "No SConstruct found")) 
          (t (find-sconstruct-r (directory-file-name parent))))))) 
    (if (buffer-file-name) 
     (catch 'found-it 
      (find-sconstruct-r (buffer-file-name))) 
     (error "Buffer is not visiting a file")))) 


(defun project-root()  
    (file-name-directory (find-sconstruct))) 

A continuación, puede cambiar su compile-command de usar, por ejemplo, project-root

(concat "cd " (project-root) " && scons") 
+0

¡Gracias! Yo uso Scons en el trabajo, pero apestaba en elisp, y esto funciona muy bien para mí. – user511493

2

Otra alternativa es fijar la variable -proceso de compilación-función de ajuste que se documenta como:

función a llamar para personalizar el proceso de compilación. Esta función se invoca inmediatamente antes de iniciarse el proceso de compilación. Es se puede utilizar para establecer las variables o funciones que se utilizan mientras procesa el resultado del proceso de compilación. La función es llamada con las variables compilation-buffer' and compilación-ventana ' vinculada al buffer de compilación y la ventana, respectivamente.

Uso Maven mucho y escribí esta biblioteca para apoyar su problema para un contexto Maven. A continuación, cambie el valor de la variable compilación de búsqueda en archivos según proceda:

;;; Support for Maven 2 

(require 'compile) 

(setq compile-search-file "pom.xml") 

(defun find-search-file() 
    ;; Search for the pom file traversing up the directory tree. 
    (setq dir (expand-file-name default-directory)) 
    (let ((parent (file-name-directory (directory-file-name dir)))) 
    (while (and (not (file-readable-p (concat dir compile-search-file))) 
     (not (string= parent dir))) 
     (setq dir parent 
     parent (file-name-directory (directory-file-name dir)))) 
    (if (string= dir parent) 
    (error "Search file %s is missing" compile-search-file) 
     (with-current-buffer compilation-last-buffer 
    (message "Test %s %s." compilation-buffer compilation-window) 
    (setq default-directory dir))))) 

;; Add the following to support Emacs' compile mode: 
(add-to-list 
'compilation-error-regexp-alist-alist 
'(mvn "^\\(.*\\):\\[\\([0-9]*\\),\\([0-9]*\\)\\]" 1 2 3)) 
(add-to-list 'compilation-error-regexp-alist 'mvn) 

(setq compilation-process-setup-function 'find-search-file) 

(provide 'maven-support) 
+0

¡Eso es genial, gracias! –

1

Acabo de empezar a trabajar en un más genérico, extensible y robusto pero todavía razonablemente rápido y sucio solución que acabo de crear. Está algo basado en el ejemplo anterior de Maven, pero prefiero no perder el tiempo con las variables globales, así que uso las formas especiales let o let * mucho más. Y, por supuesto, usa make.

Ahora solo admite Makefiles pero puede agregar una cláusula al formulario especial (cond) en la función `my-compilation-process-setup-function 'si desea admitir uno o más sistemas de compilación adicionales.

¡Incluso tiene cadenas de documentación!

Lo verá en my Github eventualmente.

Cuestiones relacionadas