LINUX.ORG.RU

Emacs: flymake, scons, C и C++


0

0

В emacs есть такая забавная шняга как flymake, и все бы хорошо, но для C и С++ flymake'у требуется Makefile. И все бы ничего, но я использую scons. Пока подружил так, для emacs:

(defun flymake-c-init ()
  (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
         (local-file  (file-relative-name
                       temp-file
                       (file-name-directory buffer-file-name))))
    (list "/home/alex/.emacs.d/tools/fly.sh" (list (concat "check=" local-file)))))
(push '("\\.c$" flymake-c-init) flymake-allowed-file-name-masks)
(push '("\\.h$" flymake-cc-init) flymake-allowed-file-name-masks)

(add-hook 'c-mode-hook
          '(lambda ()
	     (if (and (not (null buffer-file-name)) (file-writable-p buffer-file-name))
		 (flymake-mode))))

(defun flymake-cc-init ()
  (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
         (local-file  (file-relative-name
                       temp-file
                       (file-name-directory buffer-file-name))))
    (list "/home/alex/fly.sh" (list (concat "check=" local-file)))))
(push '("\\.cpp$" flymake-cc-init) flymake-allowed-file-name-masks)
(push '("\\.hpp$" flymake-cc-init) flymake-allowed-file-name-masks)

(add-hook 'c++-mode-hook
          '(lambda ()
	     (if (and (not (null buffer-file-name)) (file-writable-p buffer-file-name))
		 (flymake-mode))))
fly.sh:
#!/bin/sh

check()
{
    FILE=$(echo $1 | grep -E -o -e '[^=]*\.(c|cpp|h|hpp)$')
    case $FILE in
        *.c) gcc -Wall -fsyntax-only $FILE;;
        *.cpp|*.h|*.hpp) g++ -Wall -fsyntax-only $FILE;;
    esac
}

if [ -f SConstruct ]
then
    if [ "$(cat SConstruct | grep 'flymake on')" != "" ]
    then
        scons -Q $1
    else
        check $1
    fi
else
    check $1
fi
В SConstruct добавляется следующие:
#flymake on
import os
import re
import string

def check(env):
    flags = ""

    if re.match(".*\.c$", ARGUMENTS.get('check')) != None:
        flags += "gcc "
    else:
        if re.match(".*\.(cpp|h|hpp)$", ARGUMENTS.get('check')) != None:
            flags += "g++ "
        else:
            return

    for s in env['CPPPATH']:
        flags += "-I" + s + " "

    flags +=  "-Wall -fsyntax-only "

    flags += ARGUMENTS.get('check')

    os.system("%s" % flags)

...

if ARGUMENTS.get('check') != None:
    check(env)
    exit(0)

...
fly.sh нужен для того что бы в случае если файла SConstruct не существует, запустить команду `gcc -Wall -fsyntax-only` для файла. SConstruct используется если требуется указать путь для поиска директорий с заголовочными файлами.

И все бы ничего, но в SConstruct как-то много писать нужно, можно конечно это все в сниппеты загнать, но хотелось бы обойтись меньшими телодвижениями. Кто что подскажет?

В SConstruct сделал так:
import os
import re
import string

#flymake on
def check(env, arg):
    if arg.get('check') == None:
        return
        
    flags = ""

    if re.match(".*\.c$", arg.get('check')) != None:
        flags += "gcc "
    else:
        if re.match(".*\.(cpp|h|hpp)$", arg.get('check')) != None:
            flags += "g++ "
        else:
            return

    for s in env['CPPPATH']:
        flags += "-I" + s + " "

    flags +=  "-Wall -fsyntax-only "
    flags += arg.get('check')

    os.system("%s" % flags)

    exit(0)

...
check(env, ARGUMENTS)
...

Во fly.sh поправил следующие:
*.c) eval "gcc -Wall -fsyntax-only $FILE";;
*.cpp|*.h|*.hpp) eval "g++ -Wall -fsyntax-only $FILE";;

Так же путь для C++ указан не тот что для C.

plambir
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.