mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Cross compiling now actually works
At least for non-PyQt based extensions
This commit is contained in:
parent
d13404d9ea
commit
ef9e669ef9
@ -69,32 +69,10 @@ class Extension:
|
|||||||
self.libraries = d['libraries'] = kwargs.get('libraries', [])
|
self.libraries = d['libraries'] = kwargs.get('libraries', [])
|
||||||
self.cflags = d['cflags'] = kwargs.get('cflags', [])
|
self.cflags = d['cflags'] = kwargs.get('cflags', [])
|
||||||
self.uses_icu = 'icuuc' in self.libraries
|
self.uses_icu = 'icuuc' in self.libraries
|
||||||
if self.needs_cxx and kwargs.get('needs_c++'):
|
|
||||||
std_prefix = '/std:' if iswindows else '-std='
|
|
||||||
self.cflags.insert(0, std_prefix + 'c++' + kwargs['needs_c++'])
|
|
||||||
|
|
||||||
if iswindows:
|
|
||||||
self.cflags.append('/DCALIBRE_MODINIT_FUNC=PyMODINIT_FUNC')
|
|
||||||
else:
|
|
||||||
return_type = 'PyObject*'
|
|
||||||
extern_decl = 'extern "C"' if self.needs_cxx else ''
|
|
||||||
|
|
||||||
self.cflags.append(
|
|
||||||
'-DCALIBRE_MODINIT_FUNC='
|
|
||||||
'{} __attribute__ ((visibility ("default"))) {}'.format(extern_decl, return_type))
|
|
||||||
|
|
||||||
if kwargs.get('needs_c'):
|
|
||||||
self.cflags.insert(0, '-std=c' + kwargs['needs_c'])
|
|
||||||
|
|
||||||
self.ldflags = d['ldflags'] = kwargs.get('ldflags', [])
|
self.ldflags = d['ldflags'] = kwargs.get('ldflags', [])
|
||||||
self.optional = d['options'] = kwargs.get('optional', False)
|
self.optional = d['options'] = kwargs.get('optional', False)
|
||||||
of = kwargs.get('optimize_level', None)
|
self.needs_cxx_std = kwargs.get('needs_c++')
|
||||||
if of is None:
|
self.needs_c_std = kwargs.get('needs_c')
|
||||||
of = '/Ox' if iswindows else '-O3'
|
|
||||||
else:
|
|
||||||
flag = '/O%d' if iswindows else '-O%d'
|
|
||||||
of = flag % of
|
|
||||||
self.cflags.insert(0, of)
|
|
||||||
self.only_build_for = kwargs.get('only', '')
|
self.only_build_for = kwargs.get('only', '')
|
||||||
|
|
||||||
|
|
||||||
@ -245,6 +223,7 @@ class Environment(NamedTuple):
|
|||||||
cc_output_flag: str
|
cc_output_flag: str
|
||||||
platform_name: str
|
platform_name: str
|
||||||
dest_ext: str
|
dest_ext: str
|
||||||
|
std_prefix: str
|
||||||
|
|
||||||
def inc_dirs_to_cflags(self, dirs) -> List[str]:
|
def inc_dirs_to_cflags(self, dirs) -> List[str]:
|
||||||
return [self.external_inc_prefix+x for x in dirs]
|
return [self.external_inc_prefix+x for x in dirs]
|
||||||
@ -264,6 +243,7 @@ def init_env(debug=False, sanitize=False, compiling_for='native'):
|
|||||||
libdir_prefix = '-L'
|
libdir_prefix = '-L'
|
||||||
lib_prefix = '-l'
|
lib_prefix = '-l'
|
||||||
lib_suffix = ''
|
lib_suffix = ''
|
||||||
|
std_prefix = '-std='
|
||||||
obj_suffix = '.o'
|
obj_suffix = '.o'
|
||||||
cc_input_c_flag = cc_input_cpp_flag = '-c'
|
cc_input_c_flag = cc_input_cpp_flag = '-c'
|
||||||
cc_output_flag = '-o'
|
cc_output_flag = '-o'
|
||||||
@ -321,17 +301,18 @@ def init_env(debug=False, sanitize=False, compiling_for='native'):
|
|||||||
|
|
||||||
if iswindows or compiling_for == 'windows':
|
if iswindows or compiling_for == 'windows':
|
||||||
platform_name = 'windows'
|
platform_name = 'windows'
|
||||||
|
std_prefix = '/std:'
|
||||||
cc = cxx = win_cc
|
cc = cxx = win_cc
|
||||||
linker = win_ld
|
linker = win_ld
|
||||||
cflags, ldflags = basic_windows_flags(debug)
|
cflags, ldflags = basic_windows_flags(debug)
|
||||||
if compiling_for == 'windows':
|
if compiling_for == 'windows':
|
||||||
cc = 'clang-cl'
|
cc = cxx = 'clang-cl'
|
||||||
linker = 'lld-link'
|
linker = 'lld-link'
|
||||||
splat = '.build-cache/xwin/splat'
|
splat = '.build-cache/xwin/splat'
|
||||||
for I in 'sdk/include/um sdk/include/cppwinrt sdk/include/shared sdk/include/ucrt crt/include':
|
for I in 'sdk/include/um sdk/include/cppwinrt sdk/include/shared sdk/include/ucrt crt/include'.split():
|
||||||
cflags.append('/external:I')
|
cflags.append('/external:I')
|
||||||
cflags.append(f'{splat}/{I}')
|
cflags.append(f'{splat}/{I}')
|
||||||
for L in './sdk/lib/um/x86_64 crt/lib/x86_64':
|
for L in 'sdk/lib/um/x86_64 crt/lib/x86_64 sdk/lib/ucrt/x86_64'.split():
|
||||||
ldflags.append(f'/libpath:{splat}/{L}')
|
ldflags.append(f'/libpath:{splat}/{L}')
|
||||||
else:
|
else:
|
||||||
for p in win_inc:
|
for p in win_inc:
|
||||||
@ -359,7 +340,7 @@ def init_env(debug=False, sanitize=False, compiling_for='native'):
|
|||||||
cflags.extend('-I' + x for x in get_python_include_paths())
|
cflags.extend('-I' + x for x in get_python_include_paths())
|
||||||
ldflags.append('/LIBPATH:'+os.path.join(sysconfig.get_config_var('prefix'), 'libs'))
|
ldflags.append('/LIBPATH:'+os.path.join(sysconfig.get_config_var('prefix'), 'libs'))
|
||||||
return Environment(
|
return Environment(
|
||||||
platform_name=platform_name, dest_ext=dest_ext,
|
platform_name=platform_name, dest_ext=dest_ext, std_prefix=std_prefix,
|
||||||
cc=cc, cxx=cxx, cflags=cflags, ldflags=ldflags, linker=linker, make=NMAKE if iswindows else 'make', lib_prefix=lib_prefix,
|
cc=cc, cxx=cxx, cflags=cflags, ldflags=ldflags, linker=linker, make=NMAKE if iswindows else 'make', lib_prefix=lib_prefix,
|
||||||
obj_suffix=obj_suffix, cc_input_c_flag=cc_input_c_flag, cc_input_cpp_flag=cc_input_cpp_flag, cc_output_flag=cc_output_flag,
|
obj_suffix=obj_suffix, cc_input_c_flag=cc_input_c_flag, cc_input_cpp_flag=cc_input_cpp_flag, cc_output_flag=cc_output_flag,
|
||||||
internal_inc_prefix=internal_inc_prefix, external_inc_prefix=external_inc_prefix, libdir_prefix=libdir_prefix, lib_suffix=lib_suffix)
|
internal_inc_prefix=internal_inc_prefix, external_inc_prefix=external_inc_prefix, libdir_prefix=libdir_prefix, lib_suffix=lib_suffix)
|
||||||
@ -410,9 +391,18 @@ class Build(Command):
|
|||||||
|
|
||||||
def dump_db(self, name, db):
|
def dump_db(self, name, db):
|
||||||
os.makedirs('build', exist_ok=True)
|
os.makedirs('build', exist_ok=True)
|
||||||
|
existing = []
|
||||||
|
try:
|
||||||
|
with open(f'build/{name}_commands.json', 'rb') as f:
|
||||||
|
existing = json.load(f)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
combined = {x['output']: x for x in existing}
|
||||||
|
for x in db:
|
||||||
|
combined[x['output']] = x
|
||||||
try:
|
try:
|
||||||
with open(f'build/{name}_commands.json', 'w') as f:
|
with open(f'build/{name}_commands.json', 'w') as f:
|
||||||
json.dump(db, f, indent=2)
|
json.dump(tuple(combined.values()), f, indent=2)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
if err.errno != errno.EROFS:
|
if err.errno != errno.EROFS:
|
||||||
raise
|
raise
|
||||||
@ -525,7 +515,23 @@ class Build(Command):
|
|||||||
else:
|
else:
|
||||||
oinc = [env.cc_output_flag, obj]
|
oinc = [env.cc_output_flag, obj]
|
||||||
einc = env.inc_dirs_to_cflags(ext.inc_dirs)
|
einc = env.inc_dirs_to_cflags(ext.inc_dirs)
|
||||||
cmd = [compiler] + env.cflags + ext.cflags + einc + sinc + oinc
|
if env.cc_output_flag.startswith('/'):
|
||||||
|
cflags = ['/DCALIBRE_MODINIT_FUNC=PyMODINIT_FUNC']
|
||||||
|
else:
|
||||||
|
return_type = 'PyObject*'
|
||||||
|
extern_decl = 'extern "C"' if ext.needs_cxx else ''
|
||||||
|
cflags = [
|
||||||
|
'-DCALIBRE_MODINIT_FUNC='
|
||||||
|
'{} __attribute__ ((visibility ("default"))) {}'.format(extern_decl, return_type)]
|
||||||
|
if ext.needs_cxx and ext.needs_cxx_std:
|
||||||
|
cflags.append(env.std_prefix + 'c++' + ext.needs_cxx_std)
|
||||||
|
|
||||||
|
if ext.needs_c_std and not env.std_prefix.startswith('/'):
|
||||||
|
cflags.append(env.std_prefix + 'c' + ext.needs_c_std)
|
||||||
|
if env is self.windows_cross_env:
|
||||||
|
cflags.append('-Wno-deprecated-experimental-coroutine')
|
||||||
|
|
||||||
|
cmd = [compiler] + env.cflags + cflags + ext.cflags + einc + sinc + oinc
|
||||||
return CompileCommand(cmd, src, obj)
|
return CompileCommand(cmd, src, obj)
|
||||||
|
|
||||||
objects = []
|
objects = []
|
||||||
@ -538,8 +544,7 @@ class Build(Command):
|
|||||||
if self.newer(cc.dest, [src]+ext.headers):
|
if self.newer(cc.dest, [src]+ext.headers):
|
||||||
ans.append(cc)
|
ans.append(cc)
|
||||||
env = self.env_for_compilation_db(ext)
|
env = self.env_for_compilation_db(ext)
|
||||||
if env is None:
|
if env is not None:
|
||||||
continue
|
|
||||||
db.append({
|
db.append({
|
||||||
'arguments': get(src, env).cmd, 'directory': os.getcwd(), 'file': os.path.relpath(src, os.getcwd()),
|
'arguments': get(src, env).cmd, 'directory': os.getcwd(), 'file': os.path.relpath(src, os.getcwd()),
|
||||||
'output': os.path.relpath(cc.dest, os.getcwd())})
|
'output': os.path.relpath(cc.dest, os.getcwd())})
|
||||||
@ -550,7 +555,7 @@ class Build(Command):
|
|||||||
def get(env: Environment) -> LinkCommand:
|
def get(env: Environment) -> LinkCommand:
|
||||||
dest = self.dest(ext, env)
|
dest = self.dest(ext, env)
|
||||||
compiler = env.cxx if ext.needs_cxx else env.cc
|
compiler = env.cxx if ext.needs_cxx else env.cc
|
||||||
linker = self.env.linker or compiler
|
linker = env.linker or compiler
|
||||||
cmd = [linker]
|
cmd = [linker]
|
||||||
elib = env.lib_dirs_to_ldflags(ext.lib_dirs)
|
elib = env.lib_dirs_to_ldflags(ext.lib_dirs)
|
||||||
xlib = env.libraries_to_ldflags(ext.libraries)
|
xlib = env.libraries_to_ldflags(ext.libraries)
|
||||||
@ -559,10 +564,10 @@ class Build(Command):
|
|||||||
if ext.uses_icu:
|
if ext.uses_icu:
|
||||||
# windows has its own ICU libs that dont work
|
# windows has its own ICU libs that dont work
|
||||||
pre_ld_flags = elib
|
pre_ld_flags = elib
|
||||||
cmd += pre_ld_flags + self.env.ldflags + ext.ldflags + elib + xlib + \
|
cmd += pre_ld_flags + env.ldflags + ext.ldflags + elib + xlib + \
|
||||||
['/EXPORT:' + init_symbol_name(ext.name)] + objects + ext.extra_objs + ['/OUT:'+dest]
|
['/EXPORT:' + init_symbol_name(ext.name)] + objects + ext.extra_objs + ['/OUT:'+dest]
|
||||||
else:
|
else:
|
||||||
cmd += objects + ext.extra_objs + ['-o', dest] + self.env.ldflags + ext.ldflags + elib + xlib
|
cmd += objects + ext.extra_objs + ['-o', dest] + env.ldflags + ext.ldflags + elib + xlib
|
||||||
return LinkCommand(cmd, objects, dest)
|
return LinkCommand(cmd, objects, dest)
|
||||||
|
|
||||||
env = self.env_for_compilation_db(ext)
|
env = self.env_for_compilation_db(ext)
|
||||||
|
@ -191,7 +191,7 @@
|
|||||||
"sources": "calibre/utils/windows/winspeech.cpp",
|
"sources": "calibre/utils/windows/winspeech.cpp",
|
||||||
"libraries": "WindowsApp",
|
"libraries": "WindowsApp",
|
||||||
"needs_c++": "20",
|
"needs_c++": "20",
|
||||||
"cflags": "/X /Zc:__cplusplus /bigobj /await /permissive- /WX /Zc:twoPhase-"
|
"cflags": "/X /Zc:__cplusplus /bigobj /permissive- /WX /Zc:twoPhase-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "wpd",
|
"name": "wpd",
|
||||||
|
@ -66,14 +66,6 @@ enum {
|
|||||||
EXIT_REQUESTED
|
EXIT_REQUESTED
|
||||||
};
|
};
|
||||||
|
|
||||||
// trim from start (in place)
|
|
||||||
static inline void
|
|
||||||
ltrim(std::string &s) {
|
|
||||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
|
||||||
return !std::isspace(ch);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// trim from end (in place)
|
// trim from end (in place)
|
||||||
static inline void
|
static inline void
|
||||||
rtrim(std::string &s) {
|
rtrim(std::string &s) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user