1#!/usr/bin/env python
2# encoding: utf-8
3# DragoonX6 2018
4
5"""
6Common routines for cross_clang.py and cross_clangxx.py
7"""
8
9from waflib.Configure import conf
10import waflib.Context
11
12def normalize_target_triple(target_triple):
13	target_triple = target_triple[:-1]
14	normalized_triple = target_triple.replace('--', '-unknown-')
15
16	if normalized_triple.startswith('-'):
17		normalized_triple = 'unknown' + normalized_triple
18
19	if normalized_triple.endswith('-'):
20		normalized_triple += 'unknown'
21
22	# Normalize MinGW builds to *arch*-w64-mingw32
23	if normalized_triple.endswith('windows-gnu'):
24		normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-w64-mingw32'
25
26	# Strip the vendor when doing msvc builds, since it's unused anyway.
27	if normalized_triple.endswith('windows-msvc'):
28		normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-windows-msvc'
29
30	return normalized_triple.replace('-', '_')
31
32@conf
33def clang_modifier_msvc(conf):
34	import os
35
36	"""
37	Really basic setup to use clang in msvc mode.
38	We actually don't really want to do a lot, even though clang is msvc compatible
39	in this mode, that doesn't mean we're actually using msvc.
40	It's probably the best to leave it to the user, we can assume msvc mode if the user
41	uses the clang-cl frontend, but this module only concerns itself with the gcc-like frontend.
42	"""
43	v = conf.env
44	v.cprogram_PATTERN = '%s.exe'
45
46	v.cshlib_PATTERN   = '%s.dll'
47	v.implib_PATTERN   = '%s.lib'
48	v.IMPLIB_ST        = '-Wl,-IMPLIB:%s'
49	v.SHLIB_MARKER     = []
50
51	v.CFLAGS_cshlib    = []
52	v.LINKFLAGS_cshlib = ['-Wl,-DLL']
53	v.cstlib_PATTERN   = '%s.lib'
54	v.STLIB_MARKER     = []
55
56	del(v.AR)
57	conf.find_program(['llvm-lib', 'lib'], var='AR')
58	v.ARFLAGS          = ['-nologo']
59	v.AR_TGT_F         = ['-out:']
60
61	# Default to the linker supplied with llvm instead of link.exe or ld
62	v.LINK_CC          = v.CC + ['-fuse-ld=lld', '-nostdlib']
63	v.CCLNK_TGT_F      = ['-o']
64	v.def_PATTERN      = '-Wl,-def:%s'
65
66	v.LINKFLAGS = []
67
68	v.LIB_ST            = '-l%s'
69	v.LIBPATH_ST        = '-Wl,-LIBPATH:%s'
70	v.STLIB_ST          = '-l%s'
71	v.STLIBPATH_ST      = '-Wl,-LIBPATH:%s'
72
73	CFLAGS_CRT_COMMON = [
74		'-Xclang', '--dependent-lib=oldnames',
75		'-Xclang', '-fno-rtti-data',
76		'-D_MT'
77	]
78
79	v.CFLAGS_CRT_MULTITHREADED = CFLAGS_CRT_COMMON + [
80		'-Xclang', '-flto-visibility-public-std',
81		'-Xclang', '--dependent-lib=libcmt',
82	]
83	v.CXXFLAGS_CRT_MULTITHREADED = v.CFLAGS_CRT_MULTITHREADED
84
85	v.CFLAGS_CRT_MULTITHREADED_DBG = CFLAGS_CRT_COMMON + [
86		'-D_DEBUG',
87		'-Xclang', '-flto-visibility-public-std',
88		'-Xclang', '--dependent-lib=libcmtd',
89	]
90	v.CXXFLAGS_CRT_MULTITHREADED_DBG = v.CFLAGS_CRT_MULTITHREADED_DBG
91
92	v.CFLAGS_CRT_MULTITHREADED_DLL = CFLAGS_CRT_COMMON + [
93		'-D_DLL',
94		'-Xclang', '--dependent-lib=msvcrt'
95	]
96	v.CXXFLAGS_CRT_MULTITHREADED_DLL = v.CFLAGS_CRT_MULTITHREADED_DLL
97
98	v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = CFLAGS_CRT_COMMON + [
99		'-D_DLL',
100		'-D_DEBUG',
101		'-Xclang', '--dependent-lib=msvcrtd',
102	]
103	v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CFLAGS_CRT_MULTITHREADED_DLL_DBG
104
105@conf
106def clang_modifier_target_triple(conf, cpp=False):
107	compiler = conf.env.CXX if cpp else conf.env.CC
108	output = conf.cmd_and_log(compiler + ['-dumpmachine'], output=waflib.Context.STDOUT)
109
110	modifier = ('clangxx' if cpp else 'clang') + '_modifier_'
111	clang_modifier_func = getattr(conf, modifier + normalize_target_triple(output), None)
112	if clang_modifier_func:
113		clang_modifier_func()
114