├── LICENSE ├── README.md ├── c_cpp_properties.json ├── generate_compdb.py ├── settings.json └── tasks.json /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Visual Studio Code project for Linux kernel sources 2 | =================================================== 3 | 4 | Ensure the kernel is built (at least, all `*.cmd` files should be generated): 5 | 6 | $ make defconfig 7 | $ make 8 | 9 | Clone this repository as ".vscode": 10 | 11 | $ git clone git@github.com:amezin/vscode-linux-kernel.git .vscode 12 | 13 | Generate compile_commands.json: 14 | 15 | $ python .vscode/generate_compdb.py 16 | 17 | If you are not compiling kernel for x64, change `intelliSenseMode` in 18 | `c_cpp_properties.json`. Possible values as of vscode-cpptools 1.0.1: 19 | 20 | * `gcc-x86` 21 | * `gcc-x64` 22 | * `gcc-arm` 23 | * `gcc-arm64` 24 | 25 | Open the project: 26 | 27 | $ code . 28 | 29 | Out-of-tree builds 30 | ------------------ 31 | 32 | https://github.com/amezin/vscode-linux-kernel/issues/4 33 | 34 | Kernel can be built with separate output directory: 35 | 36 | $ make O=../linux-build defconfig 37 | $ make O=../linux-build 38 | 39 | In this case, you should pass the directory to `generate_compdb.py`: 40 | 41 | $ python .vscode/generate_compdb.py -O ../linux-build 42 | 43 | `compile_commands.json` will still be generated in the current directory (root of the `linux` repository). 44 | Unfortunately, `tasks.json` will not work out of the box in this configuration (TODO). 45 | 46 | Out-of-tree module development 47 | ------------------------------ 48 | 49 | If you build your module with this command: 50 | 51 | $ make -C $KDIR M=$PWD modules 52 | 53 | You could generate `compile_commands.json` with: 54 | 55 | $ python .vscode/generate_compdb.py -O $KDIR $PWD 56 | 57 | Example: https://github.com/amezin/nzxt-rgb-fan-controller-dkms 58 | -------------------------------------------------------------------------------- /c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "cStandard": "c11", 6 | "intelliSenseMode": "gcc-x64", 7 | "compileCommands": "${workspaceFolder}/compile_commands.json" 8 | } 9 | ], 10 | "version": 4 11 | } -------------------------------------------------------------------------------- /generate_compdb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from __future__ import print_function, division 4 | 5 | import argparse 6 | import fnmatch 7 | import functools 8 | import json 9 | import math 10 | import multiprocessing 11 | import os 12 | import re 13 | import sys 14 | 15 | 16 | CMD_VAR_RE = re.compile(r'^\s*(?:saved)?cmd_(\S+)\s*:=\s*(.+)\s*$', re.MULTILINE) 17 | SOURCE_VAR_RE = re.compile(r'^\s*source_(\S+)\s*:=\s*(.+)\s*$', re.MULTILINE) 18 | 19 | 20 | def print_progress_bar(progress): 21 | progress_bar = '[' + '|' * int(50 * progress) + '-' * int(50 * (1.0 - progress)) + ']' 22 | print('\r', progress_bar, "{0:.1%}".format(progress), end='\r', file=sys.stderr) 23 | 24 | 25 | def parse_cmd_file(out_dir, cmdfile_path): 26 | with open(cmdfile_path, 'r') as cmdfile: 27 | cmdfile_content = cmdfile.read() 28 | 29 | commands = { match.group(1): match.group(2) for match in CMD_VAR_RE.finditer(cmdfile_content) } 30 | sources = { match.group(1): match.group(2) for match in SOURCE_VAR_RE.finditer(cmdfile_content) } 31 | 32 | return [{ 33 | 'directory': out_dir, 34 | 'command': commands[o_file_name], 35 | 'file': source, 36 | 'output': o_file_name 37 | } for o_file_name, source in sources.items()] 38 | 39 | 40 | def gen_compile_commands(cmd_file_search_path, out_dir): 41 | print("Building *.o.cmd file list...", file=sys.stderr) 42 | 43 | out_dir = os.path.abspath(out_dir) 44 | 45 | if not cmd_file_search_path: 46 | cmd_file_search_path = [out_dir] 47 | 48 | cmd_files = [] 49 | for search_path in cmd_file_search_path: 50 | if (os.path.isdir(search_path)): 51 | for cur_dir, subdir, files in os.walk(search_path): 52 | cmd_files.extend(os.path.join(cur_dir, cmdfile_name) for cmdfile_name in fnmatch.filter(files, '*.o.cmd')) 53 | else: 54 | cmd_files.extend(search_path) 55 | 56 | if not cmd_files: 57 | print("No *.o.cmd files found in", ", ".join(cmd_file_search_path), file=sys.stderr) 58 | return 59 | 60 | print("Parsing *.o.cmd files...", file=sys.stderr) 61 | 62 | n_processed = 0 63 | print_progress_bar(0) 64 | 65 | compdb = [] 66 | pool = multiprocessing.Pool() 67 | try: 68 | for compdb_chunk in pool.imap_unordered(functools.partial(parse_cmd_file, out_dir), cmd_files, chunksize=int(math.sqrt(len(cmd_files)))): 69 | compdb.extend(compdb_chunk) 70 | n_processed += 1 71 | print_progress_bar(n_processed / len(cmd_files)) 72 | 73 | finally: 74 | pool.terminate() 75 | pool.join() 76 | 77 | print(file=sys.stderr) 78 | print("Writing compile_commands.json...", file=sys.stderr) 79 | 80 | with open('compile_commands.json', 'w') as compdb_file: 81 | json.dump(compdb, compdb_file, indent=1) 82 | 83 | 84 | def main(): 85 | cmd_parser = argparse.ArgumentParser() 86 | cmd_parser.add_argument('-O', '--out-dir', type=str, default=os.getcwd(), help="Build output directory") 87 | cmd_parser.add_argument('cmd_file_search_path', nargs='*', help="*.cmd file search path") 88 | gen_compile_commands(**vars(cmd_parser.parse_args())) 89 | 90 | 91 | if __name__ == '__main__': 92 | main() 93 | -------------------------------------------------------------------------------- /settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.*.*.cmd": true, 4 | "**/.*.d": true, 5 | "**/.*.S": true 6 | }, 7 | "[c]": { 8 | "editor.detectIndentation": false, 9 | "editor.tabSize": 8, 10 | "editor.insertSpaces": false, 11 | "editor.rulers": [80,100] 12 | }, 13 | "files.associations": { 14 | "*.h": "c" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Generate compile_commands.json", 8 | "type": "process", 9 | "command": "python", 10 | "args": [ 11 | "${workspaceRoot}/.vscode/generate_compdb.py" 12 | ], 13 | "problemMatcher": [] 14 | } 15 | ] 16 | } --------------------------------------------------------------------------------