Skip to content

Instantly share code, notes, and snippets.

@valzav
Created April 23, 2014 03:34
Show Gist options
  • Save valzav/11202024 to your computer and use it in GitHub Desktop.
Save valzav/11202024 to your computer and use it in GitHub Desktop.
This Ruby script extracts dependency data from CMake project (supports nested CMake files) in graphviz's dot format
#!/usr/bin/env ruby
# usage:
# ruby depscanner.rb [path_to_project_dir]
# brew install graphviz / apt-get install graphviz (if graphviz is not installed yet)
# dot -Tpng dependencies.dot -o dependencies.png
$binaries = {}
$dependencies = {}
def args_to_array(args_str)
args_str.gsub("\n", '').gsub(/\s+/, ' ').strip().split(' ')
end
def scan_cmake_file_in(dir)
file = "#{dir}/CMakeLists.txt"
return unless File.exist?(file)
puts "scanning #{file}"
File.open(file, 'r') do |f|
content = ''
f.each do |l|
next if l =~ /^\s*#/
content << l
scan_cmake_file_in("#{dir}/#{$1}") if l =~ /add_subdirectory\(\s*([\w\/]+)\s*\)/
end
content.scan(/add_library\(([^\)]+)\)/m).each do |m|
args = args_to_array(m[0])
$binaries[args[0]] = :library
end
content.scan(/add_executable\(([^\)]+)\)/m).each do |m|
args = args_to_array(m[0])
$binaries[args[0]] = :executable
end
content.scan(/target_link_libraries\(([^\)]+)\)/m).each do |m|
args = args_to_array(m[0])
$dependencies[args.shift] = args
end
end
end
project_dir = ARGV[0] || '.'
scan_cmake_file_in(project_dir.chomp('/'))
#$binaries.delete_if { |key, value| key.match(/dns/) }
$binaries.delete_if { |key, value| key.match(/test/) }
deps_graph = "digraph {\n"
deps_graph << " rankdir = LR;\n"
$binaries.each do |b,type|
if type == :library
deps_graph << " #{b} [shape = circle, fillcolor = yellow, style = filled];\n"
else
deps_graph << " #{b} [shape = circle, fillcolor = green, style = filled];\n"
end
end
$dependencies.each do |b, deps|
next unless $binaries[b]
deps.each do |d|
next unless $binaries[d]
deps_graph << " #{b} -> #{d};\n"
end
end
deps_graph << "}\n"
File.open('dependencies.dot','w') do |f|
f.write(deps_graph)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment