278 lines
6.3 KiB
Go
278 lines
6.3 KiB
Go
module main
|
|
|
|
import os
|
|
|
|
#flag -I @VROOT/thirdparty/microsoft_craziness
|
|
#flag windows @VROOT/thirdparty/microsoft_craziness/microsoft_craziness.o
|
|
#flag windows -l ole32
|
|
#flag windows -l oleaut32
|
|
#flag windows -l shell32
|
|
|
|
// Emily: If these arent included then msvc assumes that
|
|
// these return int (which should be 64bit)
|
|
// but then it goes and sign extends our pointer types anyway
|
|
// which breaks everything
|
|
#include <microsoft_craziness.h>
|
|
|
|
struct MsvcResult {
|
|
sdk_ver int
|
|
|
|
windows_sdk_root_path string
|
|
exe_path string
|
|
|
|
um_lib_path string
|
|
ucrt_lib_path string
|
|
vs_lib_path string
|
|
|
|
um_include_path string
|
|
ucrt_include_path string
|
|
vs_include_path string
|
|
shared_include_path string
|
|
}
|
|
|
|
struct FindResult {
|
|
sdk_ver int
|
|
windows_sdk_root *u16
|
|
windows_sdk_um_library_path *u16
|
|
windows_sdk_ucrt_library_path *u16
|
|
vs_exe_path *u16
|
|
vs_library_path *u16
|
|
}
|
|
|
|
fn C.find_visual_studio_and_windows_sdk() *FindResult
|
|
|
|
fn find_msvc() *MsvcResult {
|
|
$if windows {
|
|
r := C.find_visual_studio_and_windows_sdk()
|
|
|
|
windows_sdk_root := string_from_wide(r.windows_sdk_root)
|
|
ucrt_lib_folder := string_from_wide(r.windows_sdk_ucrt_library_path)
|
|
um_lib_folder := string_from_wide(r.windows_sdk_um_library_path)
|
|
vs_lib_folder := string_from_wide(r.vs_library_path)
|
|
exe_folder := string_from_wide(r.vs_exe_path)
|
|
|
|
mut ucrt_include_folder := ucrt_lib_folder.replace('Lib', 'Include')
|
|
mut vs_include_folder := vs_lib_folder.replace('lib', 'include')
|
|
|
|
if ucrt_include_folder.ends_with('\\x64') {
|
|
ucrt_include_folder = ucrt_include_folder.left(ucrt_include_folder.len - 4)
|
|
}
|
|
if vs_include_folder.ends_with('\\x64') {
|
|
vs_include_folder = vs_include_folder.left(vs_include_folder.len - 4)
|
|
}
|
|
|
|
um_include_folder := ucrt_include_folder.replace('ucrt', 'um')
|
|
shared_include_folder := ucrt_include_folder.replace('ucrt', 'shared')
|
|
|
|
return &MsvcResult {
|
|
sdk_ver: r.sdk_ver,
|
|
windows_sdk_root_path: windows_sdk_root,
|
|
exe_path: exe_folder,
|
|
|
|
um_lib_path: um_lib_folder,
|
|
ucrt_lib_path: ucrt_lib_folder,
|
|
vs_lib_path: vs_lib_folder,
|
|
|
|
um_include_path: um_include_folder,
|
|
ucrt_include_path: ucrt_include_folder,
|
|
vs_include_path: vs_include_folder,
|
|
shared_include_path: shared_include_folder,
|
|
}
|
|
}
|
|
$else {
|
|
panic('Cannot find msvc on this platform')
|
|
}
|
|
}
|
|
|
|
pub fn cc_msvc(v *V) {
|
|
r := find_msvc()
|
|
|
|
mut a := ['-w', '/volatile:ms', '/D_UNICODE', '/DUNICODE'] // arguments for the C compiler
|
|
|
|
// cl.exe is stupid so these are in a different order to the ones below!
|
|
|
|
if v.pref.is_prod {
|
|
a << '/O2'
|
|
a << '/MD'
|
|
} else {
|
|
a << '/Z7'
|
|
a << '/MDd'
|
|
}
|
|
|
|
if v.pref.is_so {
|
|
// Dont think we have to do anything for this
|
|
if !v.out_name.ends_with('.dll') {
|
|
v.out_name = v.out_name + '.dll'
|
|
}
|
|
|
|
// Build dll
|
|
a << '/LD'
|
|
} else if !v.out_name.ends_with('.exe') {
|
|
v.out_name = v.out_name + '.exe'
|
|
}
|
|
|
|
mut libs := ''// builtin.o os.o http.o etc
|
|
if v.pref.build_mode == .build {
|
|
}
|
|
else if v.pref.build_mode == .embed_vlib {
|
|
//
|
|
}
|
|
else if v.pref.build_mode == .default_mode {
|
|
libs = '"$ModPath/vlib/builtin.obj"'
|
|
if !os.file_exists(libs) {
|
|
println('`builtin.obj` not found')
|
|
exit(1)
|
|
}
|
|
for imp in v.table.imports {
|
|
if imp == 'webview' {
|
|
continue
|
|
}
|
|
libs += ' "$ModPath/vlib/${imp}.obj"'
|
|
}
|
|
}
|
|
|
|
if v.pref.sanitize {
|
|
println('Sanitize not supported on msvc.')
|
|
}
|
|
|
|
// The C file we are compiling
|
|
//a << '"$TmpPath/$v.out_name_c"'
|
|
// this isnt correct for some reason
|
|
// so fix that now
|
|
|
|
a << '".$v.out_name_c"'
|
|
|
|
mut other_flags := []string{}
|
|
mut real_libs := []string{}
|
|
mut lib_paths := []string{}
|
|
|
|
for f in v.table.flags {
|
|
// We need to see if the flag contains -l
|
|
// -l isnt recognised and these libs will be passed straight to the linker
|
|
// by the compiler
|
|
if f.starts_with('-l') {
|
|
lib_base := f.right(2).trim_space()
|
|
|
|
// MSVC has no method of linking against a .dll
|
|
// TODO: we should look for .defs aswell
|
|
lib_lib := lib_base + '.lib'
|
|
real_libs << lib_lib
|
|
}
|
|
else if f.starts_with('-L') {
|
|
lib_paths << f.right(2).trim_space()
|
|
}
|
|
else if f.ends_with('.o') {
|
|
// msvc expects .obj not .o
|
|
other_flags << f + 'bj'
|
|
}
|
|
else {
|
|
other_flags << f
|
|
}
|
|
}
|
|
|
|
default_libs := [
|
|
'kernel32.lib',
|
|
'user32.lib',
|
|
'gdi32.lib',
|
|
'winspool.lib',
|
|
'comdlg32.lib',
|
|
'advapi32.lib',
|
|
'shell32.lib',
|
|
'ole32.lib',
|
|
'oleaut32.lib',
|
|
'uuid.lib',
|
|
'odbc32.lib',
|
|
'odbccp32.lib',
|
|
'vcruntime.lib',
|
|
'kernel32.lib',
|
|
]
|
|
|
|
for l in default_libs {
|
|
real_libs << l
|
|
}
|
|
|
|
|
|
// flags := v.table.flags.join(' ')
|
|
|
|
// Include the base paths
|
|
a << '-I "$r.ucrt_include_path" -I "$r.vs_include_path" -I "$r.um_include_path" -I "$r.shared_include_path"'
|
|
|
|
// Msvc also doesnt have atomic
|
|
// TODO: dont rely on gcc's _Atomic semantics!
|
|
a << other_flags
|
|
|
|
// TODO: libs will need to be actually handled properly
|
|
a << real_libs.join(' ')
|
|
|
|
a << '/link'
|
|
a << '/NOLOGO'
|
|
a << '/OUT:$v.out_name'
|
|
a << '/LIBPATH:"$r.ucrt_lib_path"'
|
|
a << '/LIBPATH:"$r.um_lib_path"'
|
|
a << '/LIBPATH:"$r.vs_lib_path"'
|
|
a << '/INCREMENTAL:NO' // Disable incremental linking
|
|
|
|
for l in lib_paths {
|
|
a << '/LIBPATH:"$l"'
|
|
}
|
|
|
|
if !v.pref.is_prod {
|
|
a << '/DEBUG:FULL'
|
|
}
|
|
|
|
args := a.join(' ')
|
|
|
|
// println('$args')
|
|
// println('$exe_path')
|
|
|
|
escaped_path := r.exe_path
|
|
|
|
cmd := '""$escaped_path\\cl.exe" $args"'
|
|
|
|
// println('$cmd')
|
|
|
|
res := os.exec(cmd)
|
|
// println(res)
|
|
// println('C OUTPUT:')
|
|
if res.contains('error') {
|
|
println(res)
|
|
panic('msvc error')
|
|
}
|
|
|
|
if !v.pref.is_debug && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' {
|
|
os.rm('.$v.out_name_c')
|
|
}
|
|
|
|
}
|
|
|
|
fn build_thirdparty_obj_file_with_msvc(flag string) {
|
|
msvc := find_msvc()
|
|
|
|
mut obj_path := flag.all_after(' ')
|
|
|
|
if obj_path.ends_with('.o') {
|
|
// msvc expects .obj not .o
|
|
obj_path = obj_path + 'bj'
|
|
}
|
|
|
|
if os.file_exists(obj_path) {
|
|
return
|
|
}
|
|
println('$obj_path not found, building it (with msvc)...')
|
|
parent := obj_path.all_before_last('/').trim_space()
|
|
files := os.ls(parent)
|
|
|
|
mut cfiles := ''
|
|
for file in files {
|
|
if file.ends_with('.c') {
|
|
cfiles += parent + '/' + file + ' '
|
|
}
|
|
}
|
|
|
|
include_string := '-I "$msvc.ucrt_include_path" -I "$msvc.vs_include_path" -I "$msvc.um_include_path" -I "$msvc.shared_include_path"'
|
|
|
|
println('$cfiles')
|
|
|
|
res := os.exec('""$msvc.exe_path\\cl.exe" /volatile:ms /Z7 $include_string /c $cfiles /Fo"$obj_path" /D_UNICODE /DUNICODE"')
|
|
println(res)
|
|
} |