Sublime Forum

Build system result: how to parse a result line with relative path?

#1

I have setup a build system for a compiler (for KL) that outputs this kind of results:
[FABRIC:MT] [DwarfScatter] KL/Scatter/Scatter.kl:260:3: error: no resolution for method ScatterLayerSurface.relax(ScatterLayer, PaintSurface, UInt32[])
So in this case the file is “KL/Scatter/Scatter.Scatter.kl”, which is relative to the working dir of the compiler, which is NOT at the root of the sublime project.

To make things more interesting, the build result can contain lines from several compilation units (called extensions in KL), which live in different subdirectories, so for example if I have:

  • projectRoot
    • Ext1
      • Ext1File1.kl
    • Ext2
      • Ext2File1.kl

the output would be:
[FABRIC:MT] [NameOfExt1] Ext1File1.kl:1:1: bla [FABRIC:MT] [NameOfExt2] Ext2File1.kl:1:1: bla

NameOfExt1 is arbitrary, can’t necessarily be guessed from the folder name :sweat:

I don’t think I can’t sort this out with file_regex or result_file_regex --though I’d love to be proved wrong!
Is there a way to run custom code to resolve the absolute path? I’m thinking something along the lines of the selector.py I saw mentioned in the build systems doc.

0 Likes

#2

The simplest way is just to pipe the build output through a tool of your own making that resolves the absolute paths and outputs them for ST.

0 Likes

#3

There is a view setting for that named result_base_dir: http://docs.sublimetext.info/en/latest/reference/build_systems/configuration.html#capturing-build-system-results

This setting gets set by the exec command to the working_dir, which defaults to the directory of the file currently active file if it isn’t specified as an argument.

2 Likes

#4

If you’ve got your heart set on integrating into the ST side, you’d have to hack exec.py, in the Default package, which is executed when you build.

0 Likes

#5

@nutjob2: Thanks, piping is a great idea!
It seems a bit counter efficient to run another script, my first impulse was indeed to hack exec.py (ideally I would have liked to be able to set a custom py script per-build system), but piping is a much more self-contained solution.

@FichteFoll: unfortunately setting the working_dir (which I’m already doing) is not enough, because the results are not all relative to the same base path.

I first tried a python script, but unfortunately it until build completion then dumped everything… odd. A bash script with sed however, processes line by line interactively.
For whoever’s interested, here’s my project file:

	"build_systems":
	[
		// docs: http://www.sublimetext.com/docs/3/projects.html
		// variants: http://docs.sublimetext.info/en/latest/reference/build_systems/configuration.html#variants
		// ... although the ctrl+B vs ctrl+shift+B behavior described is obsolete, here's the correct one: http://stackoverflow.com/a/29290258/322119
		// 
		// We pipe the KL build results to translate_kl_build_results.sh to get paths
		// relative to the Sublime project (instead of relative to each extension).
		// http://stackoverflow.com/a/2381643/322119 to pipe stderr but not stdin
		{
			"name": "System",
			"variants":
			[
				{
					"name": "make (C++)",
					"shell_cmd": "./make_System.sh",
				},
				{
					"name": "Compile (KL)",
					"shell_cmd": "./compile_System.sh 3>&1 1>&2 2>&3 | ./translate_kl_build_results.sh",
					"file_regex": "^\\./(.*):(\\d+):(\\d+)",
				},
			],
			"working_dir": "$project_path",
		},
		... more systems here ...
	],

and the script:

#!/usr/bin/env bash

# process each line interactively (ie line will be translated as the build occurs)
while read -r line; do
	#		example input:
	#[FABRIC:MT] [DwarfCore] KL/test.kl:4:9: error: 'bla': symbol not found
	#[FABRIC:MT] [ImGui] KL/test.kl:4:9: error: 'bla': symbol not found
	# 	output:
	#./Core/KL/test.kl:4:9: error: 'bla': symbol not found
	#./ImGui/KL/test.kl:4:9: error: 'bla': symbol not found
	# 
	# So basically we replace the extension name with the folder name (ie just remove any 'Dwarf' prefix),
	# relative to the root of the Sublime project.
	# 
	# Make sure we have a line number ([0-9]+), otherwise we might catch errors that are not tied
	# to a particular file so of no interest to Sublime...
	# 
	echo $line | sed -r 's/\[FABRIC:MT\] \[(Dwarf)?(.*)\] (.*):([0-9]+)/.\/\2\/\3:\4/'
done
0 Likes

#6

The results look weird though, is that normal?

0 Likes

#7

Do you have CR’s or LF’s or other special chars in your messages? Might be an idea to sanitize them down to the printing chars and the space char.

Python probably did that becuase it didn’t flush the output buffer (until exit), a common problem.

You can also fiddle with the CSS associated with the error phantoms which might fix the problem. My theme file is (in part):

<key>background</key> <string>#FFFFFF</string> <key>caret</key> <string>#000000</string> <key>foreground</key> <string>#000000</string> <key>invisibles</key> <string>#BFBFBF</string> <key>lineHighlight</key> <string>#00000024</string> <key>selection</key> <string>#00000024</string> <key>phantomCss</key> <string><![CDATA[ div.error { color: white; background-color: #850085; font-size: 9pt; padding: 0px; margin: 0px; display: inline; font-weight: normal; position: relative; left: 0px; border-radius: 0px; } div.error a { display: none; color: #00000000; } ]]></string>

Finally, I took the extra step of hacking the exec.py to layout the phantoms at the end of the line of the error instead of underneath, and used inline layout, which seems to handle long lines better:

changed line 438 to sublime.Region(view.line(pt).end(), view.line(pt).end()),
changed line 444 to sublime.LAYOUT_INLINE,
I also added display: inline; to phantomCss.div.error so that the inline fit within the source line.

0 Likes

#8

I don’t believe so, the messages are issued by the compiler so I assume it will only print clean messages.
Do you think that’s causing the Sublime red tooltips to look broken?
At what step would this sanitization occur? I noticed the makefile package uses this (..[^:\n]*) instead of my dumb (.*) in the “file_regex”, is that what you mean?

0 Likes

#9

It might just be the CSS layout failing on the phantom by not allocating enough space for the text and unintentionally wrapping the final quoted word while not increasing the box by a line. I recommend fiddling with the CSS and reducing the padding or changing the font size. This functionality is fairly new and likely buggy.

0 Likes