3
# Given a Visual Studio project, create a CMakeLists.txt file to serve
4
# as a starting point. Supports simple DLL/Static/Executable projects,
5
# but custom build steps and build events are ignored.
7
# Author: Jesper Eskilson
8
# Email: jesper [at] eskilson [dot] se
12
require 'rexml/document'
13
include FileUtils::Verbose
15
configuration="Debug|Win32"
17
# Usage: vcproj2cmake.rb <input.vcproj> [<output CMakeLists.txt>]
20
output_file = ARGV.shift or output_file = File.join(File.dirname(filename), "CMakeLists.txt")
22
# Change \ to /, and remove leading ./
24
felems = p.gsub("\\", "/").split("/")
25
felems.shift if felems[0] == "."
29
if File.exists?(output_file)
30
mv(output_file, output_file + ".backup")
33
File.open(output_file, "w") { |out|
34
File.open(filename) { |io|
35
doc = REXML::Document.new io
37
doc.elements.each("VisualStudioProject") { |project|
38
name = project.attributes["Name"]
40
out.puts "project( #{name} )"
43
out.puts( "set(SOURCES " )
45
project.elements.each("Files//File") { |file|
47
f = normalize(file.attributes["RelativePath"])
50
next if f =~ /\.(h|H|lex|y|ico|bmp|txt)$/
52
# Ignore files which have the ExcludedFromBuild attribute set to TRUE
53
excluded_from_build = false
54
file.elements.each("FileConfiguration") { |file_config|
55
if file_config.attributes["ExcludedFromBuild"] == "TRUE"
56
excluded_from_build = true
60
# Ignore files with custom build steps
61
included_in_build = true
62
file.elements.each("FileConfiguration/Tool") { |tool|
63
if tool.attributes["Name"] == "VCCustomBuildTool"
64
included_in_build = false
68
if not excluded_from_build and included_in_build
76
project.elements.each("Configurations/Configuration[@Name=\"#{configuration}\"]") { |config|
77
config_name = config.attributes["Name"].split("|")[0]
82
use_of_mfc = config.attributes["UseOfMFC"].to_i
85
out.puts "set(CMAKE_MFC_FLAG #{use_of_mfc})"
89
config.elements.each('Tool[@Name="VCCLCompilerTool"]') { |compiler|
92
out.puts "include_directories( \n"
94
include_dirs = compiler.attributes["AdditionalIncludeDirectories"].split(/[,;]/).sort.each { |s|
95
incpath = normalize(s).strip
96
if incpath["Vc7/atlmfc/src/mfc"]
97
out.puts " ${MFC_INCLUDE}"
99
out.puts " " + incpath
105
out.puts "add_definitions( \n"
106
compiler.attributes["PreprocessorDefinitions"].split(";").sort.each { |s|
107
out.puts " -D" + s.strip
111
out.puts " -D_AFXEXT"
112
out.puts " -D_AFXDLL"
119
config_type = config.attributes["ConfigurationType"].to_i
123
if config_type == 1 # Executable
124
out.puts "add_executable( #{name} WIN32 ${SOURCES} )"
125
elsif config_type == 2 # DLL
126
out.puts "add_library( #{name} SHARED ${SOURCES} )"
127
elsif config_type == 4 # Static
128
out.puts "add_library( #{name} STATIC ${SOURCES} )"
130
$stderr.puts "Project type #{config_type} not supported."
135
config.elements.each('Tool[@Name="VCLinkerTool"]') { |linker|
136
deps = linker.attributes["AdditionalDependencies"]
137
if deps and deps.length > 0
138
out.print "target_link_libraries( #{name} "
140
deps.split.each { |lib|
141
lib = lib.gsub(/\\/, "/")
142
out.print File.basename(lib, ".lib") + " "
153
puts "Wrote #{output_file}"