The cl.exe
path that is used is using windows short-path (PROGRAM~2
) and that may be also the cause of the issue. They could be eliminated by expanding cmd[0]
in convert-compile-commands.py
, before generating the entry. One options is to use win32file.GetLongPathName()
from pywin32
.
great! will try that. What about slashes in the options? I think I remember that they were escaped in the original buildwrapper output but not in the python output. Do you think it makes sense to output \/Gy
for example?
If the short-path correction is not causing the issue, could you please share the updated build-wrapper.json
file and the sonar scanner log privately?
@michael-brade,
After investing your build-wrapper-dump.json
file and the 8.9 LTS requirements, I have found out that for MSVC
we need one additional entry in the capture list. This entry should be at the beginning of the list and have format:
{
"compiler":"msvc-cl",
"executable": *path to the compiler executable*,
"stdout": *output of the invocation to stdout*,
"stderr": *output of the invocation to stderr*
}
Also, would it be possible to share your version of the python script for conversion on the forum? It may be useful for other people visiting a forum.
Yes, thank you! That did it. So here is my updated python script:
"""
#
# Warning:
# - This is a workaround for builds where build-wrapper doesn't work
# - This is only for msvc
"""
import sys
import json
import shlex
from collections import OrderedDict
import os
import ctypes
import subprocess
def getLongPathName(path):
buf = ctypes.create_unicode_buffer(260)
GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
rv = GetLongPathName(path, buf, 260)
if rv == 0 or rv > 260:
return path
else:
return buf.value
if len(sys.argv) < 2:
sys.stderr.write("Usage: %s <path to compile_commands.json>\n" % (sys.argv[0]))
sys.exit(1)
with open(sys.argv[1]) as db_file:
db = json.load(db_file)
env = []
for k, v in os.environ.items():
env.append("%s=%s" % (k, v))
captures = []
compiler_capt = OrderedDict()
compiler_capt['compiler'] = "msvc-cl"
compiler_capt['executable'] = ""
compiler_capt['stdout'] = ""
compiler_capt['stderr'] = ""
captures.append(compiler_capt)
for entry in db:
if 'arguments' in entry:
cmd = entry['arguments']
else:
# we need to remove the ' at the beginning and the end of the string before splitting it
cmd = shlex.quote(entry['command'])[1:-1].split()
# rc.exe entries are not needed for sonar
if cmd[0].endswith('rc.exe'):
continue
cmd[0] = getLongPathName(cmd[0])
capture = OrderedDict()
capture['compiler'] = 'msvc-cl'
capture['cwd'] = entry['directory']
capture['executable'] = cmd[0]
capture['cmd'] = cmd
capture['env'] = env
captures.append(capture)
result = subprocess.run(captures[1]['executable'], capture_output=True)
captures[0]['executable'] = captures[1]['executable']
captures[0]['stdout'] = result.stdout.decode('cp850')
captures[0]['stderr'] = result.stderr.decode('cp850')
bw = OrderedDict()
bw['version'] = 0
bw['captures'] = captures
os.makedirs('bw-outputs', exist_ok=True)
with open('bw-outputs/build-wrapper-dump.json', 'w') as bw_file:
json.dump(bw, bw_file, indent = 2)
print('File created: bw-outputs/build-wrapper-dump.json')
Maybe the conversion to long path names is not actually needed, maybe rc.exe could be left in the dump â I didnât test that because it works now You will have to call it from Jenkinsfile like this:
bat """
set path=%path:"=%
call "${env.VS_VCVARS}"
python.exe convert-compile-commands.py build\\compile_commands.json
"""
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.