1

Compiling code with GCC or Clang can result in some colorful error outputs.

Linking code, however, doesn't enjoy the same luxury. It seems like the GNU Linker doesn't support colorized error output right out of the box.

Is there a way around this? Is it possible to colorize/stylize linker errors from ld?

3
  • "Probably?" What would you color, specifically? Commented Feb 24, 2019 at 14:49
  • Personally? The file name and the offset within the file. But of course any scheme that would make linker errors easier to read is fine Commented Feb 24, 2019 at 15:01
  • It's just that your question is broadly phrased; if I colored the first letter of every line green, that's technically an answer to your question, but probably not what you're after, which is why I asked for clarification. Commented Feb 24, 2019 at 15:02

2 Answers 2

1

You could use a universal wrapper like grc.

Creating the following configuration file conf.ld:

# file with extension regexp=\w+\.\w+ colours=green - # offset regexp=\(.+\) colours=yellow - # symbol regexp=`.+\' colours=bright_red 

and piping the ld output to grcat

$ ld lib.o main.o /lib/x86_64-linux-gnu/crt1.o -lc -o main 2>&1 | grcat ./conf.ld ld: lib.o: in function `f2': lib.c:(.text+0xe): undefined reference to `f3' ld: main.o: in function `main': main.c:(.text+0x9): undefined reference to `f1' 

some parts of the output are colored.

In my terminal it looks like this:

terminal capture

0

You can have a simple wrapper script to colorize ld output.

I have the following script saved as /usr/local/bin/ld which assumes that the real ld is at /usr/bin/ld.

Now I can change my PATH to point to this directory:
export PATH="/usr/local/bin:${PATH}"

Save as /usr/local/bin/ld and do chmod +x /usr/local/bin/ld

#!/usr/bin/env python3 import subprocess import sys import re RED = '\033[91m' GREEN = '\033[92m' ENDC = '\033[0m' def colorize_output(line): pattern = r'([\/\w\.-]+):(\d+)' colored_line = re.sub(pattern, RED + r'\1' + ENDC + ':' + GREEN + r'\2' + ENDC, line) return colored_line def run_ld(args): process = subprocess.Popen(['/usr/bin/ld'] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: output = process.stdout.readline() if not output and process.poll() is not None: break if output: print(colorize_output(output.decode()), end='') while True: output = process.stderr.readline() if not output and process.poll() is not None: break if output: print(colorize_output(output.decode()), end='') return process.poll() if __name__ == '__main__': # Pass all arguments to the ld command exit_code = run_ld(sys.argv[1:]) sys.exit(exit_code) 

The only thing is that this script would first print stderr and then stdout.

A more sophisticated script could scan the path to find the right ld.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.