Reputation: 309
I'm using Flymake for C code syntax checking. If the Makefile and the source file are located in the same directory, Flymake works fine. But if the Makefile is in the parent directory of the source code (like in most C projects), it seems like that Flymake can't find the Makefile anymore, and produces the following message in the *Flymake log*
buffer:
Warning [flymake hello.c]: Disabling backend flymake-cc because make: *** No rule to make target `check-syntax'. Stop.
I'm using the default configuration of Flymake. The C source code and the Makefile for testing are listed at the end of this post. I saw many people are using custom init functions for Flymake. But I found that the default init function for Flymake was able to locate the Makefile correctly, at least for C projects. For example, if I evaluate flymake-proc-simple-make-init
within the src/hello.c
buffer, I got this message:
("make" ("-s" "-C" "../" "CHK_SOURCES=src/hello_140332961481000_flymake.c" "SYNTAX_CHECK_MODE=1" "check-syntax"))
The "-C" "../"
part indicates that it knows the Makefile is located in the directory one level up. I can't find out why it didn't work eventually.
What I want to achieve are:
Any help would be appreciated.
$ tree .
.
|-- Makefile
|-- main.c
`-- src
|-- hello.c
`-- hello.h
# Makefile
INCLUDE=src
check-syntax:
clang -fsyntax-only -Wall -I${INCLUDE} ${CHK_SOURCES} || true
/* main.c */
#include "hello.h"
int main(void)
{
hello()
return 0;
}
/* src/hello.c */
#include "hello.h"
#include <stdio.h>
void hello(void)
{
printf("hello\n")
}
/* src/hello.h */
#ifndef HELLO_H
#define HELLO_H
void hello(void);
#endif
Upvotes: 3
Views: 317
Reputation: 309
After some research, I've found my way to solve this problem. Note that I'm still very new to Emacs, so this is probably not the best solution. But it works for me, and requires very little customization. Any better solutions or further improvements are welcome.
When editing C source code, I was using c-mode
. In c-mode
, Flymake uses flymake-cc
as its backend by default, not the legacy proc
mode. In this case, flymake-cc-command
is the command used by Flymake to generate the make
command for syntax checking. The default output of flymake-cc-command
on the src/hello.c
buffer is
("make" "check-syntax" "CHK_SOURCES=-x c -c -")
which clearly doesn't try to locate the Makefile
anywhere else other than the current directory.
But I already knew that the proc
backend was able to find the Makefile
correctly. Why don't I combine these two backends? Maybe I could achieve my goal with very little effort.
Then I found out that the flymake-proc--init-find-buildfile-dir
function from the proc
backend was what I needed. It produces the path of the Makefile
of the project and does nothing more.
Here is the customized function I got now. Pretty much the same with the original value of flymake-cc-command
, with only one new line added.
(defun flymake-cc-init ()
"Construct proper make command with CHK_SOURCES and the correct Makefile."
`("make" "check-syntax" "-C"
,(flymake-proc--init-find-buildfile-dir (buffer-file-name) "Makefile")
,(format "CHK_SOURCES=-x %s -c -"
(cond ((derived-mode-p 'c++-mode) "c++")
(t "c")))))
Upvotes: 1