Sublime Forum

Build system with recursive make

#1

I have a custom build system in my project that I modeled after the Sublime Text 3 Make build system:

{ "name": "CustomMake", "working_dir": "${folder}/src", "file_regex": "^(..^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$", "shell": true, "shell_cmd": "make -j4", "syntax": "Packages/Makefile/Make.build-language" }
Unfortunately, the make is recursive, so when there is an error in a subdirectory, the error regex thinks the file is in the directory where I called make. The command output looks like:

make all-recursive Making all in libmrc Making all in include make[3]: Nothing to be done for `all'. Making all in src make[3]: Nothing to be done for `all'. Making all in tests CC test_mrc_f3.o test_mrc_f3.c:11:2: error: #error make[3]: *** [test_mrc_f3.o] Error 1 make[2]: *** [all-recursive] Error 1 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2
Double clicking on the error line brings me to a new file src/test_mrc_f3.c, when the real file is in src/libmrc/tests/test_mrc_f3.c. I can’t come up with a way to use file_regex and line_regex to make this work. Is there any solution to this?

0 Likes

Capture errors in custom build
#2

The file_regex and line_regex aren’t powerful enough to help in this situation.

One option is to modify the Makefile to pass full paths to gcc, rather than relative ones: then gcc will use the full path in error messages. e.g., gcc $PWD/file.c rather than gcc file.c

0 Likes

#3

Unfortunately flattening the Makefile is not in the cards. I was able to get this to work by piping the make output through an external script like so:

// in the build system "shell_cmd": "make -w 2>&1 | sublemake"

[code]#!/usr/bin/env python

file: sublemake

import sys
import os.path
import re

cdir = “”

enter_re = re.compile(r"make[0-9]+]: Entering directory\s+`(.)’")
err_re = re.compile(r"(…^:\n]
):([0-9]+:?[0-9]+?:? .*)$")

for line in iter(sys.stdin.readline, b’’):
err = re.match(err_re, line)
if err:
sys.stdout.write("{0}/{1}:{2}\n".format(cdir, err.group(1),
err.group(2)))
continue

enter = re.match(enter_re, line)
if enter:
    cdir = os.path.relpath(enter.group(1))
    continue

sys.stdout.write(line)[/code]

Is there a way that I can write a plugin to capture the build output and modify it before going to the output view? Looking at Packages/Default/exec.py, I have an idea where that would go, but I’m not sure how to intercept that in a plugin. It would be nice if this functionality was all handled in sublime text, rather than needing an external tool on the PATH.

0 Likes