parent
5421c24ea0
commit
32be9bd6de
|
@ -0,0 +1,4 @@
|
|||
## Executable gains vs_module_defs keyword
|
||||
|
||||
This allows using a .def file to control which functions an [[executable]] will
|
||||
expose to a [[shared_module]].
|
|
@ -44,3 +44,13 @@ kwargs:
|
|||
type: bool
|
||||
since: 0.49.0
|
||||
description: Build a position-independent executable.
|
||||
|
||||
vs_module_defs:
|
||||
type: str | file | custom_tgt | custom_idx
|
||||
since: 1.3.0
|
||||
description: |
|
||||
Specify a Microsoft module definition file for controlling symbol exports,
|
||||
etc., on platforms where that is possible (e.g. Windows).
|
||||
|
||||
This can be used to expose which functions a shared_module loaded by an
|
||||
executable will be allowed to use.
|
||||
|
|
|
@ -3248,6 +3248,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
|||
commands += linker.gen_import_library_args(self.get_import_filename(target))
|
||||
if target.pie:
|
||||
commands += linker.get_pie_link_args()
|
||||
if target.vs_module_defs and hasattr(linker, 'gen_vs_module_defs_args'):
|
||||
commands += linker.gen_vs_module_defs_args(target.vs_module_defs.rel_to_builddir(self.build_to_src))
|
||||
elif isinstance(target, build.SharedLibrary):
|
||||
if isinstance(target, build.SharedModule):
|
||||
commands += linker.get_std_shared_module_link_args(target.get_options())
|
||||
|
|
|
@ -1530,7 +1530,7 @@ class Vs2010Backend(backends.Backend):
|
|||
# DLLs built with MSVC always have an import library except when
|
||||
# they're data-only DLLs, but we don't support those yet.
|
||||
ET.SubElement(link, 'ImportLibrary').text = target.get_import_filename()
|
||||
if isinstance(target, build.SharedLibrary):
|
||||
if isinstance(target, (build.SharedLibrary, build.Executable)):
|
||||
# Add module definitions file, if provided
|
||||
if target.vs_module_defs:
|
||||
relpath = os.path.join(down, target.vs_module_defs.rel_to_builddir(self.build_to_src))
|
||||
|
|
|
@ -114,7 +114,7 @@ known_build_target_kwargs = (
|
|||
rust_kwargs |
|
||||
cs_kwargs)
|
||||
|
||||
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie'}
|
||||
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie', 'vs_module_defs'}
|
||||
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions', 'rust_abi'}
|
||||
known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs', 'rust_abi'}
|
||||
known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink', 'rust_abi'}
|
||||
|
@ -1702,6 +1702,28 @@ class BuildTarget(Target):
|
|||
'use shared_library() with `override_options: [\'b_lundef=false\']` instead.')
|
||||
link_target.force_soname = True
|
||||
|
||||
def process_vs_module_defs_kw(self, kwargs: T.Dict[str, T.Any]) -> None:
|
||||
if kwargs.get('vs_module_defs') is None:
|
||||
return
|
||||
|
||||
path: T.Union[str, File, CustomTarget, CustomTargetIndex] = kwargs['vs_module_defs']
|
||||
if isinstance(path, str):
|
||||
if os.path.isabs(path):
|
||||
self.vs_module_defs = File.from_absolute_file(path)
|
||||
else:
|
||||
self.vs_module_defs = File.from_source_file(self.environment.source_dir, self.subdir, path)
|
||||
elif isinstance(path, File):
|
||||
# When passing a generated file.
|
||||
self.vs_module_defs = path
|
||||
elif isinstance(path, (CustomTarget, CustomTargetIndex)):
|
||||
# When passing output of a Custom Target
|
||||
self.vs_module_defs = File.from_built_file(path.get_subdir(), path.get_filename())
|
||||
else:
|
||||
raise InvalidArguments(
|
||||
'vs_module_defs must be either a string, '
|
||||
'a file object, a Custom Target, or a Custom Target Index')
|
||||
self.process_link_depends(path)
|
||||
|
||||
class FileInTargetPrivateDir:
|
||||
"""Represents a file with the path '/path/to/build/target_private_dir/fname'.
|
||||
target_private_dir is the return value of get_target_private_dir which is e.g. 'subdir/target.p'.
|
||||
|
@ -1925,6 +1947,9 @@ class Executable(BuildTarget):
|
|||
# Remember that this exe was returned by `find_program()` through an override
|
||||
self.was_returned_by_find_program = False
|
||||
|
||||
self.vs_module_defs: T.Optional[File] = None
|
||||
self.process_vs_module_defs_kw(kwargs)
|
||||
|
||||
def post_init(self) -> None:
|
||||
super().post_init()
|
||||
machine = self.environment.machines[self.for_machine]
|
||||
|
@ -2321,24 +2346,7 @@ class SharedLibrary(BuildTarget):
|
|||
self.darwin_versions = (self.soversion, self.soversion)
|
||||
|
||||
# Visual Studio module-definitions file
|
||||
if kwargs.get('vs_module_defs') is not None:
|
||||
path = kwargs['vs_module_defs']
|
||||
if isinstance(path, str):
|
||||
if os.path.isabs(path):
|
||||
self.vs_module_defs = File.from_absolute_file(path)
|
||||
else:
|
||||
self.vs_module_defs = File.from_source_file(self.environment.source_dir, self.subdir, path)
|
||||
elif isinstance(path, File):
|
||||
# When passing a generated file.
|
||||
self.vs_module_defs = path
|
||||
elif isinstance(path, (CustomTarget, CustomTargetIndex)):
|
||||
# When passing output of a Custom Target
|
||||
self.vs_module_defs = File.from_built_file(path.get_subdir(), path.get_filename())
|
||||
else:
|
||||
raise InvalidArguments(
|
||||
'Shared library vs_module_defs must be either a string, '
|
||||
'a file object, a Custom Target, or a Custom Target Index')
|
||||
self.process_link_depends(path)
|
||||
self.process_vs_module_defs_kw(kwargs)
|
||||
|
||||
rust_abi = kwargs.get('rust_abi')
|
||||
rust_crate_type = kwargs.get('rust_crate_type')
|
||||
|
|
|
@ -341,6 +341,7 @@ class _LibraryMixin(TypedDict):
|
|||
class Executable(_BuildTarget):
|
||||
|
||||
gui_app: T.Optional[bool]
|
||||
vs_module_defs: T.Optional[T.Union[str, File, build.CustomTarget, build.CustomTargetIndex]]
|
||||
win_subsystem: T.Optional[str]
|
||||
|
||||
|
||||
|
|
|
@ -601,6 +601,7 @@ _EXCLUSIVE_EXECUTABLE_KWS: T.List[KwargInfo] = [
|
|||
EXECUTABLE_KWS = [
|
||||
*_BUILD_TARGET_KWS,
|
||||
*_EXCLUSIVE_EXECUTABLE_KWS,
|
||||
_VS_MODULE_DEFS_KW.evolve(since='1.3.0', since_values=None),
|
||||
]
|
||||
|
||||
# Arguments exclusive to library types
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
EXPORTS
|
||||
exefunc
|
|
@ -1,5 +1,5 @@
|
|||
project('generated_dll_module_defs', 'c')
|
||||
|
||||
subdir('subdir')
|
||||
exe = executable('prog', 'prog.c', link_with : shlib)
|
||||
exe = executable('prog', 'prog.c', link_with : shlib, vs_module_defs : 'exe.def')
|
||||
test('runtest', exe)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
int somedllfunc(void);
|
||||
|
||||
int main(void) {
|
||||
return somedllfunc() == 42 ? 0 : 1;
|
||||
int exefunc(void) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
return somedllfunc() == exefunc() ? 0 : 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue