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:
- Make Flymake work for all the source code files in the testing project below.
- As few customization as possible.
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
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
. Inc-mode
, Flymake usesflymake-cc
as its backend by default, not the legacyproc
mode. In this case,flymake-cc-command
is the command used by Flymake to generate themake
command for syntax checking. The default output offlymake-cc-command
on thesrc/hello.c
buffer iswhich 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 theMakefile
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 theproc
backend was what I needed. It produces the path of theMakefile
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.