Skip to content

Commit

Permalink
feat(rake): generate compile_commands.json
Browse files Browse the repository at this point in the history
  • Loading branch information
berdal84 committed Jan 22, 2025
1 parent 8979d97 commit 4e4ca05
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 56 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ _screenshots/
.gitconfig
.cache

# Generate by a rake task, try `rake <target>:clangd`
.clangd
# Generate by rake
compile_commands.json
83 changes: 29 additions & 54 deletions rake/_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ def compile_file(src, target)
cmd += format_includes(target)
cmd += format_defines(target)
cmd += get_dependency_flags(src)
cmd += ["-o", src_to_obj( src ), src]
obj = src_to_obj( src )
cmd += ["-MJ", obj.ext("o.json")] # Write a compilation database entry per input, see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-MJ-arg
cmd += ["-o", obj, src]

# Run the command
sh "#{cmd.join(" ")}", verbose: VERBOSE
Expand All @@ -164,29 +166,6 @@ def link_binary( target )
sh "#{$linker} #{compiler_flags} #{defines} -o #{binary_path} #{objects} #{linker_flags}", verbose: VERBOSE
end

def get_clangd_yaml(target)
# Note:
# I couln't get the formatting I wanted (no double quotes on strings)
# That's why I do manually, but it is simple.
#
# Format documentation: https://clangd.llvm.org/config#compileflags
#
cmd = get_compile_file_command("fake.cpp", target)
flags = cmd.split(" ") # remove program name

result = "#
# .clang file generated for target #{target.name}, #{DateTime.now}
# !This file has been generated by nodable's rake script
# Do not modify it manually, edit _utils.rb instead!
#
CompileFlags:
Add: [#{flags.join(",")}]
Compiler: #{$cxx_compiler}
"
result
end

def format_defines(target)
target.defines.map{|d| "-D\"#{d}\"" }
end
Expand Down Expand Up @@ -236,6 +215,29 @@ def copy_asset(source, destination)
puts " Copy asset: #{source} => #{destination}"
end

def update_compile_commands_json()
# Generate compile_commands.json for clangd
output_file = "./compile_commands.json"

# clear existing file
if File.exist? output_file
FileUtils.rm_f output_file
end

# Grab all *.o.json files from object dir
command_files = FileList["#{OBJ_DIR}/**/*.json"]

# combine
commands = command_files.map{|f| File.read(f)}.join()
content = "[" + commands[0...-2] + "]" # -2: remove trailing comma
File.write( output_file, content)

# debug log
if VERBOSE
puts content
end
end

def tasks_for_target(target)

objects = get_self_objects(target)
Expand Down Expand Up @@ -291,7 +293,9 @@ def tasks_for_target(target)
puts "#{target.name} | Linking '#{get_binary_path(target)}' DONE"
end

multitask :compile_objects => objects_with_deps
multitask :compile_objects => objects_with_deps do
update_compile_commands_json()
end

desc "Run #{target.name}"
task :run => :build do
Expand All @@ -312,33 +316,4 @@ def tasks_for_target(target)
compile_file( src, target)
end
end

# Return the command to compile a given file
#
# File don't need to exists since nothing run,
# we simplify build the command as string and return it via stdout.
#
task :compile_command, [:filename] do |t, args|
filename = args[:filename] || "file.cpp"
puts get_compile_file_command( filename, target)
end

# Generates a clangd yaml file from target
# Save it as .clangd to enable clangd to analyze your code.
task :clangd do

file_path = ".clangd"
puts "Generating #{file_path} yaml file ..."

data = get_clangd_yaml(target)

if ( File.exists?(file_path))
puts " #{file_path} already exists, removing existing file"
File.delete(file_path)
end
puts " writing #{file_path} ..."
File.write(file_path, data)
puts " #{file_path} updated with the following data:"
puts data
end
end

0 comments on commit 4e4ca05

Please sign in to comment.