Developer's Blog

[Objective-C in Emacs] Check the syntax in flymake

Today, I want to introduce a little bit about checking syntax with flymake.
When I started writing Objective-C, the device I was using wasn’t that great so I didn’t try using it, but now I am using a much better device so I thought I’d give it a go.

The default compiler of Xcode is LLVM, so instead of gcc, clang is used. In order so that the errors and warnings outputted by Xcode are as similar as possible, I have referred to the xcodebuild option. There is a chance that this may differ depending on the settings of the project, so please make any modifications if necessary.

I have been working in the development of both Sleipnir Mobile for iPhone/iPad and Sleipnir for Mac, and because both have different build settings, when writing the settings to Emacs Lisp, switching can be a real pain.
As it is possible to perform syntax checks using Makefile with flymake, I decided to write Makefile for each one. The source file of flymake targets will be located in the current directory, so leaving everything in the same directory is recommended.

Changing the settings of SDK, OS_VER_MIN, INCLUDES, FRAMEWORKS in response to each project, should make everything work properly. Please also add libraries, etc. to INCLUDES and FRAMEWORKS if they are located in another directory.

Makefile (Mac):

CLANG	    = /usr/bin/clang
ARCH	    = -arch i386
SDK	    = -isysroot /Developer/SDKs/MacOSX10.7.sdk
OS_VER_MIN  = -mmacosx-version-min=10.6
OPTIONS     = -fsyntax-only -x objective-c -std=gnu99
WARNINGS    = -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value
INCLUDES    = -I.
FRAMEWORKS  = -F../

check-syntax:
	$(CLANG) $(OPTIONS) $(ARCH) $(WARNINGS) $(SDK) $(OS_VER_MIN) $(INCLUDES) $(FRAMEWORKS) ${CHK_SOURCES}

 

Makefile (iOS):

CLANG	    = /usr/bin/clang
ARCH	    = -arch armv7
SDK	    = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
OS_VER_MIN  = -miphoneos-version-min=4.3
OPTIONS     = -fsyntax-only -x objective-c -std=gnu99
WARNINGS    = -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value
INCLUDES    = -I.
FRAMEWORKS  = -F../

check-syntax:
	$(CLANG) $(OPTIONS) $(ARCH) $(WARNINGS) $(SDK) $(OS_VER_MIN) $(INCLUDES) $(FRAMEWORKS) ${CHK_SOURCES}

 

Emacs Lisp (Settings for flymake):

(require 'flymake)

(defun flymake-display-err-minibuffer ()
  (interactive)
  (let* ((line-no (flymake-current-line-no))
         (line-err-info-list 
           (nth 0 (flymake-find-err-info flymake-err-info line-no)))
         (count (length line-err-info-list)))
    (while (> count 0)
      (when line-err-info-list
        (let* ((file (flymake-ler-file (nth (1- count) line-err-info-list)))
               (full-file (flymake-ler-full-file 
                            (nth (1- count) line-err-info-list)))
               (text (flymake-ler-text (nth (1- count) line-err-info-list)))
               (line (flymake-ler-line (nth (1- count) line-err-info-list))))
          (message "[%s] %s" line text)))
      (setq count (1- count)))))

(defun flymake-display-err-minibuffer-safe () 
  (ignore-errors flymake-display-err-minibuffer))

;; Closes flymake when an error occurs
(defadvice flymake-post-syntax-check (before flymake-force-check-was-interrupted)
  (setq flymake-check-was-interrupted t))
(ad-activate 'flymake-post-syntax-check)

;; Added because it did not match the original pattern
(setq flymake-err-line-patterns
 (cons
  '("\\(.+\\):\\([0-9]+\\):\\([0-9]+\\): \\(.+\\)" 1 2 3 4)
  flymake-err-line-patterns))

;; flymake colour
(set-face-background 'flymake-warnline "dark orange")
(set-face-foreground 'flymake-warnline "black")
(set-face-background 'flymake-errline "orange red")
(set-face-foreground 'flymake-errline "black")

(add-hook 'objc-mode-hook
         (lambda ()
           (push '("\\.m$" flymake-simple-make-init) flymake-allowed-file-name-masks)
           (push '("\\.h$" flymake-simple-make-init) flymake-allowed-file-name-masks)
           (define-key objc-mode-map "\C-cd" 'flymake-display-err-minibuf)))
           (flymake-mode t)
         ))

 

Well, everything did run quite well, but I think that the automatic building of Xcode4 probably works a bit better.
However, I just don’t want to use any other editors anymore. I want to keep adding useful functions to Emacs so it can’t lose to anything else.

Please join us on Facebook for Sleipnir for Windows!


Please follow us on Twitter!

Facebook Comments