Merge pull request #2711 from xclaesse/both-library
Add both_library() to build both shared and static library
This commit is contained in:
commit
aef1a81b35
|
@ -112,6 +112,24 @@ run. The behavior of this function is identical to `test` with the
|
||||||
exception that there is no `is_parallel` keyword, because benchmarks
|
exception that there is no `is_parallel` keyword, because benchmarks
|
||||||
are never run in parallel.
|
are never run in parallel.
|
||||||
|
|
||||||
|
### both_libraries()
|
||||||
|
|
||||||
|
``` meson
|
||||||
|
buildtarget both_libraries(library_name, list_of_sources, ...)
|
||||||
|
```
|
||||||
|
|
||||||
|
Builds both a static and shared library with the given sources. Positional and
|
||||||
|
keyword arguments are otherwise the same as for [`library`](#library). Source
|
||||||
|
files will be compiled only once and object files will be reused to build both
|
||||||
|
shared and static libraries, unless `b_staticpic` user option or `pic` argument
|
||||||
|
are set to false in which case sources will be compiled twice.
|
||||||
|
|
||||||
|
The returned [buildtarget](#build-target-object) always represents the shared
|
||||||
|
library. In addition it supports the following extra methods:
|
||||||
|
|
||||||
|
- `get_shared_lib()` returns the shared library build target
|
||||||
|
- `get_static_lib()` returns the static library build target
|
||||||
|
|
||||||
### build_target()
|
### build_target()
|
||||||
|
|
||||||
Creates a build target whose type can be set dynamically with the
|
Creates a build target whose type can be set dynamically with the
|
||||||
|
@ -885,10 +903,11 @@ dropped. That means that `join_paths('foo', '/bar')` returns `/bar`.
|
||||||
buildtarget library(library_name, list_of_sources, ...)
|
buildtarget library(library_name, list_of_sources, ...)
|
||||||
```
|
```
|
||||||
|
|
||||||
Builds a library that is either static or shared depending on the
|
Builds a library that is either static, shared or both depending on the value of
|
||||||
value of `default_library` user option. You should use this instead of
|
`default_library` user option. You should use this instead of
|
||||||
[`shared_library`](#shared_library) or
|
[`shared_library`](#shared_library),
|
||||||
[`static_library`](#static_library) most of the time. This allows you
|
[`static_library`](#static_library) or
|
||||||
|
[`both_libraries`](#both_libraries) most of the time. This allows you
|
||||||
to toggle your entire project (including subprojects) from shared to
|
to toggle your entire project (including subprojects) from shared to
|
||||||
static with only one option.
|
static with only one option.
|
||||||
|
|
||||||
|
@ -911,7 +930,8 @@ The keyword arguments for this are the same as for [`executable`](#executable) w
|
||||||
libraries. Defaults to `dylib` for shared libraries and `rlib` for
|
libraries. Defaults to `dylib` for shared libraries and `rlib` for
|
||||||
static libraries.
|
static libraries.
|
||||||
|
|
||||||
`static_library` and `shared_library` also accept these keyword arguments.
|
`static_library`, `shared_library` and `both_libraries` also accept these keyword
|
||||||
|
arguments.
|
||||||
|
|
||||||
### message()
|
### message()
|
||||||
|
|
||||||
|
@ -1670,7 +1690,8 @@ These are objects returned by the [functions listed above](#functions).
|
||||||
### `build target` object
|
### `build target` object
|
||||||
|
|
||||||
A build target is either an [executable](#executable),
|
A build target is either an [executable](#executable),
|
||||||
[shared](#shared_library), [static library](#static_library) or
|
[shared library](#shared_library), [static library](#static_library),
|
||||||
|
[both shared and static library](#both_libraries) or
|
||||||
[shared module](#shared_module).
|
[shared module](#shared_module).
|
||||||
|
|
||||||
- `extract_all_objects()` is same as `extract_objects` but returns all
|
- `extract_all_objects()` is same as `extract_objects` but returns all
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
## Building both shared and static libraries
|
||||||
|
|
||||||
|
A new function `both_libraries()` has been added to build both shared and static
|
||||||
|
libraries at the same time. Source files will be compiled only once and object
|
||||||
|
files will be reused to build both shared and static libraries, unless
|
||||||
|
`b_staticpic` user option or `pic` argument are set to false in which case
|
||||||
|
sources will be compiled twice.
|
||||||
|
|
||||||
|
The returned `buildtarget` object always represents the shared library.
|
|
@ -22,6 +22,7 @@ import json
|
||||||
import subprocess
|
import subprocess
|
||||||
from ..mesonlib import MesonException
|
from ..mesonlib import MesonException
|
||||||
from ..mesonlib import get_compiler_for_source, classify_unity_sources
|
from ..mesonlib import get_compiler_for_source, classify_unity_sources
|
||||||
|
from ..mesonlib import File
|
||||||
from ..compilers import CompilerArgs
|
from ..compilers import CompilerArgs
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import shlex
|
import shlex
|
||||||
|
@ -414,11 +415,20 @@ class Backend:
|
||||||
objname = objname.replace('/', '_').replace('\\', '_')
|
objname = objname.replace('/', '_').replace('\\', '_')
|
||||||
objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
|
objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
|
||||||
return [objpath]
|
return [objpath]
|
||||||
for osrc in extobj.srclist:
|
|
||||||
|
sources = list(extobj.srclist)
|
||||||
|
for gensrc in extobj.genlist:
|
||||||
|
for s in gensrc.get_outputs():
|
||||||
|
path = self.get_target_generated_dir(extobj.target, gensrc, s)
|
||||||
|
dirpart, fnamepart = os.path.split(path)
|
||||||
|
sources.append(File(True, dirpart, fnamepart))
|
||||||
|
|
||||||
|
for osrc in sources:
|
||||||
objname = self.object_filename_from_source(extobj.target, osrc, False)
|
objname = self.object_filename_from_source(extobj.target, osrc, False)
|
||||||
if objname:
|
if objname:
|
||||||
objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
|
objpath = os.path.join(proj_dir_to_build_root, targetdir, objname)
|
||||||
result.append(objpath)
|
result.append(objpath)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_pch_include_args(self, compiler, target):
|
def get_pch_include_args(self, compiler, target):
|
||||||
|
|
|
@ -26,67 +26,64 @@ from .mesonlib import get_filenames_templates_dict, substitute_values
|
||||||
from .mesonlib import for_windows, for_darwin, for_cygwin, for_android, has_path_sep
|
from .mesonlib import for_windows, for_darwin, for_cygwin, for_android, has_path_sep
|
||||||
from .compilers import is_object, clike_langs, sort_clike, lang_suffixes
|
from .compilers import is_object, clike_langs, sort_clike, lang_suffixes
|
||||||
|
|
||||||
known_basic_kwargs = {'install': True,
|
pch_kwargs = set(['c_pch', 'cpp_pch'])
|
||||||
'c_pch': True,
|
|
||||||
'cpp_pch': True,
|
|
||||||
'c_args': True,
|
|
||||||
'objc_args': True,
|
|
||||||
'objcpp_args': True,
|
|
||||||
'cpp_args': True,
|
|
||||||
'cs_args': True,
|
|
||||||
'vala_args': True,
|
|
||||||
'fortran_args': True,
|
|
||||||
'd_args': True,
|
|
||||||
'd_import_dirs': True,
|
|
||||||
'd_unittest': True,
|
|
||||||
'd_module_versions': True,
|
|
||||||
'java_args': True,
|
|
||||||
'rust_args': True,
|
|
||||||
'link_args': True,
|
|
||||||
'link_depends': True,
|
|
||||||
'link_with': True,
|
|
||||||
'link_whole': True,
|
|
||||||
'implicit_include_directories': True,
|
|
||||||
'include_directories': True,
|
|
||||||
'dependencies': True,
|
|
||||||
'install_dir': True,
|
|
||||||
'main_class': True,
|
|
||||||
'name_suffix': True,
|
|
||||||
'gui_app': True,
|
|
||||||
'extra_files': True,
|
|
||||||
'install_rpath': True,
|
|
||||||
'build_rpath': True,
|
|
||||||
'resources': True,
|
|
||||||
'sources': True,
|
|
||||||
'objects': True,
|
|
||||||
'native': True,
|
|
||||||
'build_by_default': True,
|
|
||||||
'override_options': True,
|
|
||||||
}
|
|
||||||
|
|
||||||
# These contain kwargs supported by both static and shared libraries. These are
|
lang_arg_kwargs = set([
|
||||||
# combined here because a library() call might be shared_library() or
|
'c_args',
|
||||||
# static_library() at runtime based on the configuration.
|
'cpp_args',
|
||||||
# FIXME: Find a way to pass that info down here so we can have proper target
|
'd_args',
|
||||||
# kwargs checking when specifically using shared_library() or static_library().
|
'd_import_dirs',
|
||||||
known_lib_kwargs = known_basic_kwargs.copy()
|
'd_unittest',
|
||||||
known_lib_kwargs.update({'version': True, # Only for shared libs
|
'd_module_versions',
|
||||||
'soversion': True, # Only for shared libs
|
'fortran_args',
|
||||||
'name_prefix': True,
|
'java_args',
|
||||||
'vs_module_defs': True, # Only for shared libs
|
'objc_args',
|
||||||
'vala_header': True,
|
'objcpp_args',
|
||||||
'vala_vapi': True,
|
'rust_args',
|
||||||
'vala_gir': True,
|
'vala_args',
|
||||||
'pic': True, # Only for static libs
|
'cs_args',
|
||||||
'rust_crate_type': True, # Only for Rust libs
|
])
|
||||||
})
|
|
||||||
|
|
||||||
known_exe_kwargs = known_basic_kwargs.copy()
|
vala_kwargs = set(['vala_header', 'vala_gir', 'vala_vapi'])
|
||||||
known_exe_kwargs.update({'implib': True,
|
rust_kwargs = set(['rust_crate_type'])
|
||||||
'export_dynamic': True
|
cs_kwargs = set(['resources', 'cs_args'])
|
||||||
})
|
|
||||||
known_jar_kwargs = known_basic_kwargs.copy()
|
buildtarget_kwargs = set([
|
||||||
known_jar_kwargs.update({'target_type': 'jar'})
|
'build_by_default',
|
||||||
|
'build_rpath',
|
||||||
|
'dependencies',
|
||||||
|
'extra_files',
|
||||||
|
'gui_app',
|
||||||
|
'link_with',
|
||||||
|
'link_whole',
|
||||||
|
'link_args',
|
||||||
|
'link_depends',
|
||||||
|
'implicit_include_directories',
|
||||||
|
'include_directories',
|
||||||
|
'install',
|
||||||
|
'install_rpath',
|
||||||
|
'install_dir',
|
||||||
|
'name_prefix',
|
||||||
|
'name_suffix',
|
||||||
|
'native',
|
||||||
|
'objects',
|
||||||
|
'override_options',
|
||||||
|
'sources',
|
||||||
|
])
|
||||||
|
|
||||||
|
known_build_target_kwargs = (
|
||||||
|
buildtarget_kwargs |
|
||||||
|
lang_arg_kwargs |
|
||||||
|
pch_kwargs |
|
||||||
|
vala_kwargs |
|
||||||
|
rust_kwargs |
|
||||||
|
cs_kwargs)
|
||||||
|
|
||||||
|
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic'}
|
||||||
|
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs'}
|
||||||
|
known_shmod_kwargs = known_build_target_kwargs
|
||||||
|
known_stlib_kwargs = known_build_target_kwargs | {'pic'}
|
||||||
|
known_jar_kwargs = known_exe_kwargs | {'main_class'}
|
||||||
|
|
||||||
class InvalidArguments(MesonException):
|
class InvalidArguments(MesonException):
|
||||||
pass
|
pass
|
||||||
|
@ -214,9 +211,10 @@ class ExtractedObjects:
|
||||||
'''
|
'''
|
||||||
Holds a list of sources for which the objects must be extracted
|
Holds a list of sources for which the objects must be extracted
|
||||||
'''
|
'''
|
||||||
def __init__(self, target, srclist, is_unity):
|
def __init__(self, target, srclist, genlist, is_unity):
|
||||||
self.target = target
|
self.target = target
|
||||||
self.srclist = srclist
|
self.srclist = srclist
|
||||||
|
self.genlist = genlist
|
||||||
if is_unity:
|
if is_unity:
|
||||||
self.check_unity_compatible()
|
self.check_unity_compatible()
|
||||||
|
|
||||||
|
@ -337,6 +335,8 @@ a hard error in the future.''' % name)
|
||||||
|
|
||||||
|
|
||||||
class BuildTarget(Target):
|
class BuildTarget(Target):
|
||||||
|
known_kwargs = known_build_target_kwargs
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||||
super().__init__(name, subdir, subproject, True)
|
super().__init__(name, subdir, subproject, True)
|
||||||
self.is_cross = is_cross
|
self.is_cross = is_cross
|
||||||
|
@ -396,7 +396,7 @@ class BuildTarget(Target):
|
||||||
def check_unknown_kwargs(self, kwargs):
|
def check_unknown_kwargs(self, kwargs):
|
||||||
# Override this method in derived classes that have more
|
# Override this method in derived classes that have more
|
||||||
# keywords.
|
# keywords.
|
||||||
self.check_unknown_kwargs_int(kwargs, known_basic_kwargs)
|
self.check_unknown_kwargs_int(kwargs, self.known_kwargs)
|
||||||
|
|
||||||
def check_unknown_kwargs_int(self, kwargs, known_kwargs):
|
def check_unknown_kwargs_int(self, kwargs, known_kwargs):
|
||||||
unknowns = []
|
unknowns = []
|
||||||
|
@ -626,13 +626,17 @@ class BuildTarget(Target):
|
||||||
if not isinstance(src, str):
|
if not isinstance(src, str):
|
||||||
raise MesonException('Object extraction arguments must be strings.')
|
raise MesonException('Object extraction arguments must be strings.')
|
||||||
src = File(False, self.subdir, src)
|
src = File(False, self.subdir, src)
|
||||||
|
# FIXME: It could be a generated source
|
||||||
if src not in self.sources:
|
if src not in self.sources:
|
||||||
raise MesonException('Tried to extract unknown source %s.' % src)
|
raise MesonException('Tried to extract unknown source %s.' % src)
|
||||||
obj_src.append(src)
|
obj_src.append(src)
|
||||||
return ExtractedObjects(self, obj_src, self.is_unity)
|
return ExtractedObjects(self, obj_src, [], self.is_unity)
|
||||||
|
|
||||||
def extract_all_objects(self):
|
def extract_all_objects(self):
|
||||||
return ExtractedObjects(self, self.sources, self.is_unity)
|
# FIXME: We should add support for transitive extract_objects()
|
||||||
|
if self.objects:
|
||||||
|
raise MesonException('Cannot extract objects from a target that itself has extracted objects')
|
||||||
|
return ExtractedObjects(self, self.sources, self.generated, self.is_unity)
|
||||||
|
|
||||||
def get_all_link_deps(self):
|
def get_all_link_deps(self):
|
||||||
return self.get_transitive_link_deps()
|
return self.get_transitive_link_deps()
|
||||||
|
@ -1184,6 +1188,8 @@ class GeneratedList:
|
||||||
return self.extra_args
|
return self.extra_args
|
||||||
|
|
||||||
class Executable(BuildTarget):
|
class Executable(BuildTarget):
|
||||||
|
known_kwargs = known_exe_kwargs
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||||
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
|
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
|
||||||
# Unless overridden, executables have no suffix or prefix. Except on
|
# Unless overridden, executables have no suffix or prefix. Except on
|
||||||
|
@ -1239,9 +1245,6 @@ class Executable(BuildTarget):
|
||||||
def type_suffix(self):
|
def type_suffix(self):
|
||||||
return "@exe"
|
return "@exe"
|
||||||
|
|
||||||
def check_unknown_kwargs(self, kwargs):
|
|
||||||
self.check_unknown_kwargs_int(kwargs, known_exe_kwargs)
|
|
||||||
|
|
||||||
def get_import_filename(self):
|
def get_import_filename(self):
|
||||||
"""
|
"""
|
||||||
The name of the import library that will be outputted by the compiler
|
The name of the import library that will be outputted by the compiler
|
||||||
|
@ -1259,6 +1262,8 @@ class Executable(BuildTarget):
|
||||||
return self.is_linkwithable
|
return self.is_linkwithable
|
||||||
|
|
||||||
class StaticLibrary(BuildTarget):
|
class StaticLibrary(BuildTarget):
|
||||||
|
known_kwargs = known_stlib_kwargs
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||||
if 'pic' not in kwargs and 'b_staticpic' in environment.coredata.base_options:
|
if 'pic' not in kwargs and 'b_staticpic' in environment.coredata.base_options:
|
||||||
kwargs['pic'] = environment.coredata.base_options['b_staticpic'].value
|
kwargs['pic'] = environment.coredata.base_options['b_staticpic'].value
|
||||||
|
@ -1297,9 +1302,6 @@ class StaticLibrary(BuildTarget):
|
||||||
def type_suffix(self):
|
def type_suffix(self):
|
||||||
return "@sta"
|
return "@sta"
|
||||||
|
|
||||||
def check_unknown_kwargs(self, kwargs):
|
|
||||||
self.check_unknown_kwargs_int(kwargs, known_lib_kwargs)
|
|
||||||
|
|
||||||
def process_kwargs(self, kwargs, environment):
|
def process_kwargs(self, kwargs, environment):
|
||||||
super().process_kwargs(kwargs, environment)
|
super().process_kwargs(kwargs, environment)
|
||||||
if 'rust_crate_type' in kwargs:
|
if 'rust_crate_type' in kwargs:
|
||||||
|
@ -1313,6 +1315,8 @@ class StaticLibrary(BuildTarget):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class SharedLibrary(BuildTarget):
|
class SharedLibrary(BuildTarget):
|
||||||
|
known_kwargs = known_shlib_kwargs
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||||
self.soversion = None
|
self.soversion = None
|
||||||
self.ltversion = None
|
self.ltversion = None
|
||||||
|
@ -1501,9 +1505,6 @@ class SharedLibrary(BuildTarget):
|
||||||
else:
|
else:
|
||||||
raise InvalidArguments('Invalid rust_crate_type "{0}": must be a string.'.format(rust_crate_type))
|
raise InvalidArguments('Invalid rust_crate_type "{0}": must be a string.'.format(rust_crate_type))
|
||||||
|
|
||||||
def check_unknown_kwargs(self, kwargs):
|
|
||||||
self.check_unknown_kwargs_int(kwargs, known_lib_kwargs)
|
|
||||||
|
|
||||||
def get_import_filename(self):
|
def get_import_filename(self):
|
||||||
"""
|
"""
|
||||||
The name of the import library that will be outputted by the compiler
|
The name of the import library that will be outputted by the compiler
|
||||||
|
@ -1559,6 +1560,8 @@ class SharedLibrary(BuildTarget):
|
||||||
# A shared library that is meant to be used with dlopen rather than linking
|
# A shared library that is meant to be used with dlopen rather than linking
|
||||||
# into something else.
|
# into something else.
|
||||||
class SharedModule(SharedLibrary):
|
class SharedModule(SharedLibrary):
|
||||||
|
known_kwargs = known_shmod_kwargs
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||||
if 'version' in kwargs:
|
if 'version' in kwargs:
|
||||||
raise MesonException('Shared modules must not specify the version kwarg.')
|
raise MesonException('Shared modules must not specify the version kwarg.')
|
||||||
|
@ -1568,19 +1571,20 @@ class SharedModule(SharedLibrary):
|
||||||
self.import_filename = None
|
self.import_filename = None
|
||||||
|
|
||||||
class CustomTarget(Target):
|
class CustomTarget(Target):
|
||||||
known_kwargs = {'input': True,
|
known_kwargs = set([
|
||||||
'output': True,
|
'input',
|
||||||
'command': True,
|
'output',
|
||||||
'capture': False,
|
'command',
|
||||||
'install': True,
|
'capture',
|
||||||
'install_dir': True,
|
'install',
|
||||||
'build_always': True,
|
'install_dir',
|
||||||
'depends': True,
|
'build_always',
|
||||||
'depend_files': True,
|
'depends',
|
||||||
'depfile': True,
|
'depend_files',
|
||||||
'build_by_default': True,
|
'depfile',
|
||||||
'override_options': True,
|
'build_by_default',
|
||||||
}
|
'override_options',
|
||||||
|
])
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False):
|
def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False):
|
||||||
super().__init__(name, subdir, subproject, False)
|
super().__init__(name, subdir, subproject, False)
|
||||||
|
@ -1814,6 +1818,8 @@ class RunTarget(Target):
|
||||||
return "@run"
|
return "@run"
|
||||||
|
|
||||||
class Jar(BuildTarget):
|
class Jar(BuildTarget):
|
||||||
|
known_kwargs = known_jar_kwargs
|
||||||
|
|
||||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||||
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
|
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
|
||||||
for s in self.sources:
|
for s in self.sources:
|
||||||
|
@ -1836,9 +1842,6 @@ class Jar(BuildTarget):
|
||||||
# All jar targets are installable.
|
# All jar targets are installable.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def check_unknown_kwargs(self, kwargs):
|
|
||||||
self.check_unknown_kwargs_int(kwargs, known_jar_kwargs)
|
|
||||||
|
|
||||||
class CustomTargetIndex:
|
class CustomTargetIndex:
|
||||||
|
|
||||||
"""A special opaque object returned by indexing a CustomTarget. This object
|
"""A special opaque object returned by indexing a CustomTarget. This object
|
||||||
|
|
|
@ -422,7 +422,7 @@ builtin_options = {
|
||||||
'werror': [UserBooleanOption, 'Treat warnings as errors.', False],
|
'werror': [UserBooleanOption, 'Treat warnings as errors.', False],
|
||||||
'warning_level': [UserComboOption, 'Compiler warning level to use.', ['1', '2', '3'], '1'],
|
'warning_level': [UserComboOption, 'Compiler warning level to use.', ['1', '2', '3'], '1'],
|
||||||
'layout': [UserComboOption, 'Build directory layout.', ['mirror', 'flat'], 'mirror'],
|
'layout': [UserComboOption, 'Build directory layout.', ['mirror', 'flat'], 'mirror'],
|
||||||
'default_library': [UserComboOption, 'Default library type.', ['shared', 'static'], 'shared'],
|
'default_library': [UserComboOption, 'Default library type.', ['shared', 'static', 'both'], 'shared'],
|
||||||
'backend': [UserComboOption, 'Backend to use.', backendlist, 'ninja'],
|
'backend': [UserComboOption, 'Backend to use.', backendlist, 'ninja'],
|
||||||
'stdsplit': [UserBooleanOption, 'Split stdout and stderr in test logs.', True],
|
'stdsplit': [UserBooleanOption, 'Split stdout and stderr in test logs.', True],
|
||||||
'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests.", True],
|
'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests.", True],
|
||||||
|
|
|
@ -605,6 +605,31 @@ class StaticLibraryHolder(BuildTargetHolder):
|
||||||
class SharedLibraryHolder(BuildTargetHolder):
|
class SharedLibraryHolder(BuildTargetHolder):
|
||||||
def __init__(self, target, interp):
|
def __init__(self, target, interp):
|
||||||
super().__init__(target, interp)
|
super().__init__(target, interp)
|
||||||
|
# Set to True only when called from self.func_shared_lib().
|
||||||
|
target.shared_library_only = False
|
||||||
|
|
||||||
|
class BothLibrariesHolder(BuildTargetHolder):
|
||||||
|
def __init__(self, shared_holder, static_holder, interp):
|
||||||
|
# FIXME: This build target always represents the shared library, but
|
||||||
|
# that should be configurable.
|
||||||
|
super().__init__(shared_holder.held_object, interp)
|
||||||
|
self.shared_holder = shared_holder
|
||||||
|
self.static_holder = static_holder
|
||||||
|
self.methods.update({'get_shared_lib': self.get_shared_lib_method,
|
||||||
|
'get_static_lib': self.get_static_lib_method,
|
||||||
|
})
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
r = '<{} {}: {}, {}: {}>'
|
||||||
|
h1 = self.shared_holder.held_object
|
||||||
|
h2 = self.static_holder.held_object
|
||||||
|
return r.format(self.__class__.__name__, h1.get_id(), h1.filename, h2.get_id(), h2.filename)
|
||||||
|
|
||||||
|
def get_shared_lib_method(self, args, kwargs):
|
||||||
|
return self.shared_holder
|
||||||
|
|
||||||
|
def get_static_lib_method(self, args, kwargs):
|
||||||
|
return self.static_holder
|
||||||
|
|
||||||
class SharedModuleHolder(BuildTargetHolder):
|
class SharedModuleHolder(BuildTargetHolder):
|
||||||
def __init__(self, target, interp):
|
def __init__(self, target, interp):
|
||||||
|
@ -1418,71 +1443,17 @@ class MesonMain(InterpreterObject):
|
||||||
raise InterpreterException('Unknown cross property: %s.' % propname)
|
raise InterpreterException('Unknown cross property: %s.' % propname)
|
||||||
|
|
||||||
|
|
||||||
pch_kwargs = set(['c_pch', 'cpp_pch'])
|
known_library_kwargs = (
|
||||||
|
build.known_shlib_kwargs |
|
||||||
|
build.known_stlib_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
lang_arg_kwargs = set([
|
known_build_target_kwargs = (
|
||||||
'c_args',
|
known_library_kwargs |
|
||||||
'cpp_args',
|
build.known_exe_kwargs |
|
||||||
'd_args',
|
build.known_jar_kwargs |
|
||||||
'd_import_dirs',
|
{'target_type'}
|
||||||
'd_unittest',
|
)
|
||||||
'd_module_versions',
|
|
||||||
'fortran_args',
|
|
||||||
'java_args',
|
|
||||||
'objc_args',
|
|
||||||
'objcpp_args',
|
|
||||||
'rust_args',
|
|
||||||
'vala_args',
|
|
||||||
'cs_args',
|
|
||||||
])
|
|
||||||
|
|
||||||
vala_kwargs = set(['vala_header', 'vala_gir', 'vala_vapi'])
|
|
||||||
rust_kwargs = set(['rust_crate_type'])
|
|
||||||
cs_kwargs = set(['resources', 'cs_args'])
|
|
||||||
|
|
||||||
buildtarget_kwargs = set([
|
|
||||||
'build_by_default',
|
|
||||||
'build_rpath',
|
|
||||||
'dependencies',
|
|
||||||
'extra_files',
|
|
||||||
'gui_app',
|
|
||||||
'link_with',
|
|
||||||
'link_whole',
|
|
||||||
'link_args',
|
|
||||||
'link_depends',
|
|
||||||
'implicit_include_directories',
|
|
||||||
'include_directories',
|
|
||||||
'install',
|
|
||||||
'install_rpath',
|
|
||||||
'install_dir',
|
|
||||||
'name_prefix',
|
|
||||||
'name_suffix',
|
|
||||||
'native',
|
|
||||||
'objects',
|
|
||||||
'override_options',
|
|
||||||
'pic',
|
|
||||||
'sources',
|
|
||||||
'vs_module_defs',
|
|
||||||
])
|
|
||||||
|
|
||||||
build_target_common_kwargs = (
|
|
||||||
buildtarget_kwargs |
|
|
||||||
lang_arg_kwargs |
|
|
||||||
pch_kwargs |
|
|
||||||
vala_kwargs |
|
|
||||||
rust_kwargs |
|
|
||||||
cs_kwargs)
|
|
||||||
|
|
||||||
exe_kwargs = (build_target_common_kwargs) | {'implib', 'export_dynamic'}
|
|
||||||
shlib_kwargs = (build_target_common_kwargs) | {'version', 'soversion'}
|
|
||||||
shmod_kwargs = shlib_kwargs
|
|
||||||
stlib_kwargs = shlib_kwargs
|
|
||||||
|
|
||||||
jar_kwargs = exe_kwargs.copy()
|
|
||||||
jar_kwargs.update(['main_class'])
|
|
||||||
|
|
||||||
build_target_kwargs = exe_kwargs.copy()
|
|
||||||
build_target_kwargs.update(['target_type'])
|
|
||||||
|
|
||||||
permitted_kwargs = {'add_global_arguments': {'language'},
|
permitted_kwargs = {'add_global_arguments': {'language'},
|
||||||
'add_global_link_arguments': {'language'},
|
'add_global_link_arguments': {'language'},
|
||||||
|
@ -1491,12 +1462,12 @@ permitted_kwargs = {'add_global_arguments': {'language'},
|
||||||
'add_project_arguments': {'language'},
|
'add_project_arguments': {'language'},
|
||||||
'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env'},
|
'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env'},
|
||||||
'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'},
|
'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'},
|
||||||
'build_target': build_target_kwargs,
|
'build_target': known_build_target_kwargs,
|
||||||
'configure_file': {'input', 'output', 'configuration', 'command', 'install_dir', 'capture', 'install'},
|
'configure_file': {'input', 'output', 'configuration', 'command', 'install_dir', 'capture', 'install'},
|
||||||
'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
|
'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
|
||||||
'dependency': {'default_options', 'fallback', 'language', 'main', 'method', 'modules', 'optional_modules', 'native', 'required', 'static', 'version'},
|
'dependency': {'default_options', 'fallback', 'language', 'main', 'method', 'modules', 'optional_modules', 'native', 'required', 'static', 'version'},
|
||||||
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'link_whole', 'version'},
|
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'link_whole', 'version'},
|
||||||
'executable': exe_kwargs,
|
'executable': build.known_exe_kwargs,
|
||||||
'find_program': {'required', 'native'},
|
'find_program': {'required', 'native'},
|
||||||
'generator': {'arguments', 'output', 'depfile', 'capture', 'preserve_path_from'},
|
'generator': {'arguments', 'output', 'depfile', 'capture', 'preserve_path_from'},
|
||||||
'include_directories': {'is_system'},
|
'include_directories': {'is_system'},
|
||||||
|
@ -1504,12 +1475,14 @@ permitted_kwargs = {'add_global_arguments': {'language'},
|
||||||
'install_headers': {'install_dir', 'subdir'},
|
'install_headers': {'install_dir', 'subdir'},
|
||||||
'install_man': {'install_dir'},
|
'install_man': {'install_dir'},
|
||||||
'install_subdir': {'exclude_files', 'exclude_directories', 'install_dir', 'install_mode', 'strip_directory'},
|
'install_subdir': {'exclude_files', 'exclude_directories', 'install_dir', 'install_mode', 'strip_directory'},
|
||||||
'jar': jar_kwargs,
|
'jar': build.known_jar_kwargs,
|
||||||
'project': {'version', 'meson_version', 'default_options', 'license', 'subproject_dir'},
|
'project': {'version', 'meson_version', 'default_options', 'license', 'subproject_dir'},
|
||||||
'run_target': {'command', 'depends'},
|
'run_target': {'command', 'depends'},
|
||||||
'shared_library': shlib_kwargs,
|
'shared_library': build.known_shlib_kwargs,
|
||||||
'shared_module': shmod_kwargs,
|
'shared_module': build.known_shmod_kwargs,
|
||||||
'static_library': stlib_kwargs,
|
'static_library': build.known_stlib_kwargs,
|
||||||
|
'both_libraries': known_library_kwargs,
|
||||||
|
'library': known_library_kwargs,
|
||||||
'subdir': {'if_found'},
|
'subdir': {'if_found'},
|
||||||
'subproject': {'version', 'default_options'},
|
'subproject': {'version', 'default_options'},
|
||||||
'test': {'args', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'},
|
'test': {'args', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'},
|
||||||
|
@ -1610,6 +1583,7 @@ class Interpreter(InterpreterBase):
|
||||||
'shared_library': self.func_shared_lib,
|
'shared_library': self.func_shared_lib,
|
||||||
'shared_module': self.func_shared_module,
|
'shared_module': self.func_shared_module,
|
||||||
'static_library': self.func_static_lib,
|
'static_library': self.func_static_lib,
|
||||||
|
'both_libraries': self.func_both_lib,
|
||||||
'test': self.func_test,
|
'test': self.func_test,
|
||||||
'vcs_tag': self.func_vcs_tag,
|
'vcs_tag': self.func_vcs_tag,
|
||||||
'subdir_done': self.func_subdir_done,
|
'subdir_done': self.func_subdir_done,
|
||||||
|
@ -2539,20 +2513,24 @@ root and issuing %s.
|
||||||
|
|
||||||
@permittedKwargs(permitted_kwargs['shared_library'])
|
@permittedKwargs(permitted_kwargs['shared_library'])
|
||||||
def func_shared_lib(self, node, args, kwargs):
|
def func_shared_lib(self, node, args, kwargs):
|
||||||
return self.build_target(node, args, kwargs, SharedLibraryHolder)
|
holder = self.build_target(node, args, kwargs, SharedLibraryHolder)
|
||||||
|
holder.held_object.shared_library_only = True
|
||||||
|
return holder
|
||||||
|
|
||||||
|
@permittedKwargs(permitted_kwargs['both_libraries'])
|
||||||
|
def func_both_lib(self, node, args, kwargs):
|
||||||
|
return self.build_both_libraries(node, args, kwargs)
|
||||||
|
|
||||||
@permittedKwargs(permitted_kwargs['shared_module'])
|
@permittedKwargs(permitted_kwargs['shared_module'])
|
||||||
def func_shared_module(self, node, args, kwargs):
|
def func_shared_module(self, node, args, kwargs):
|
||||||
return self.build_target(node, args, kwargs, SharedModuleHolder)
|
return self.build_target(node, args, kwargs, SharedModuleHolder)
|
||||||
|
|
||||||
|
@permittedKwargs(permitted_kwargs['library'])
|
||||||
def func_library(self, node, args, kwargs):
|
def func_library(self, node, args, kwargs):
|
||||||
if self.coredata.get_builtin_option('default_library') == 'shared':
|
return self.build_library(node, args, kwargs)
|
||||||
return self.func_shared_lib(node, args, kwargs)
|
|
||||||
return self.func_static_lib(node, args, kwargs)
|
|
||||||
|
|
||||||
@permittedKwargs(permitted_kwargs['jar'])
|
@permittedKwargs(permitted_kwargs['jar'])
|
||||||
def func_jar(self, node, args, kwargs):
|
def func_jar(self, node, args, kwargs):
|
||||||
kwargs['target_type'] = 'jar'
|
|
||||||
return self.build_target(node, args, kwargs, JarHolder)
|
return self.build_target(node, args, kwargs, JarHolder)
|
||||||
|
|
||||||
@permittedKwargs(permitted_kwargs['build_target'])
|
@permittedKwargs(permitted_kwargs['build_target'])
|
||||||
|
@ -2561,15 +2539,17 @@ root and issuing %s.
|
||||||
raise InterpreterException('Missing target_type keyword argument')
|
raise InterpreterException('Missing target_type keyword argument')
|
||||||
target_type = kwargs.pop('target_type')
|
target_type = kwargs.pop('target_type')
|
||||||
if target_type == 'executable':
|
if target_type == 'executable':
|
||||||
return self.func_executable(node, args, kwargs)
|
return self.build_target(node, args, kwargs, ExecutableHolder)
|
||||||
elif target_type == 'shared_library':
|
elif target_type == 'shared_library':
|
||||||
return self.func_shared_lib(node, args, kwargs)
|
return self.build_target(node, args, kwargs, SharedLibraryHolder)
|
||||||
elif target_type == 'static_library':
|
elif target_type == 'static_library':
|
||||||
return self.func_static_lib(node, args, kwargs)
|
return self.build_target(node, args, kwargs, StaticLibraryHolder)
|
||||||
|
elif target_type == 'both_libraries':
|
||||||
|
return self.build_both_libraries(node, args, kwargs)
|
||||||
elif target_type == 'library':
|
elif target_type == 'library':
|
||||||
return self.func_library(node, args, kwargs)
|
return self.build_library(node, args, kwargs)
|
||||||
elif target_type == 'jar':
|
elif target_type == 'jar':
|
||||||
return self.func_jar(node, args, kwargs)
|
return self.build_target(node, args, kwargs, JarHolder)
|
||||||
else:
|
else:
|
||||||
raise InterpreterException('Unknown target_type.')
|
raise InterpreterException('Unknown target_type.')
|
||||||
|
|
||||||
|
@ -3222,6 +3202,41 @@ different subdirectory.
|
||||||
if idname not in self.coredata.target_guids:
|
if idname not in self.coredata.target_guids:
|
||||||
self.coredata.target_guids[idname] = str(uuid.uuid4()).upper()
|
self.coredata.target_guids[idname] = str(uuid.uuid4()).upper()
|
||||||
|
|
||||||
|
def build_both_libraries(self, node, args, kwargs):
|
||||||
|
shared_holder = self.build_target(node, args, kwargs, SharedLibraryHolder)
|
||||||
|
|
||||||
|
# Check if user forces non-PIC static library.
|
||||||
|
pic = True
|
||||||
|
if 'pic' in kwargs:
|
||||||
|
pic = kwargs['pic']
|
||||||
|
elif 'b_staticpic' in self.environment.coredata.base_options:
|
||||||
|
pic = self.environment.coredata.base_options['b_staticpic'].value
|
||||||
|
|
||||||
|
if pic:
|
||||||
|
# Exclude sources from args and kwargs to avoid building them twice
|
||||||
|
static_args = [args[0]]
|
||||||
|
static_kwargs = kwargs.copy()
|
||||||
|
static_kwargs['sources'] = []
|
||||||
|
static_kwargs['objects'] = shared_holder.held_object.extract_all_objects()
|
||||||
|
else:
|
||||||
|
static_args = args
|
||||||
|
static_kwargs = kwargs
|
||||||
|
|
||||||
|
static_holder = self.build_target(node, static_args, static_kwargs, StaticLibraryHolder)
|
||||||
|
|
||||||
|
return BothLibrariesHolder(shared_holder, static_holder, self)
|
||||||
|
|
||||||
|
def build_library(self, node, args, kwargs):
|
||||||
|
default_library = self.coredata.get_builtin_option('default_library')
|
||||||
|
if default_library == 'shared':
|
||||||
|
return self.build_target(node, args, kwargs, SharedLibraryHolder)
|
||||||
|
elif default_library == 'static':
|
||||||
|
return self.build_target(node, args, kwargs, StaticLibraryHolder)
|
||||||
|
elif default_library == 'both':
|
||||||
|
return self.build_both_libraries(node, args, kwargs)
|
||||||
|
else:
|
||||||
|
raise InterpreterException('Unknown default_library value: %s.', default_library)
|
||||||
|
|
||||||
def build_target(self, node, args, kwargs, targetholder):
|
def build_target(self, node, args, kwargs, targetholder):
|
||||||
if not args:
|
if not args:
|
||||||
raise InterpreterException('Target does not have a name.')
|
raise InterpreterException('Target does not have a name.')
|
||||||
|
@ -3257,7 +3272,13 @@ different subdirectory.
|
||||||
mlog.debug('Unknown target type:', str(targetholder))
|
mlog.debug('Unknown target type:', str(targetholder))
|
||||||
raise RuntimeError('Unreachable code')
|
raise RuntimeError('Unreachable code')
|
||||||
self.kwarg_strings_to_includedirs(kwargs)
|
self.kwarg_strings_to_includedirs(kwargs)
|
||||||
|
|
||||||
|
# Filter out kwargs from other target types. For example 'soversion'
|
||||||
|
# passed to library() when default_library == 'static'.
|
||||||
|
kwargs = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs}
|
||||||
|
|
||||||
target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objs, self.environment, kwargs)
|
target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objs, self.environment, kwargs)
|
||||||
|
|
||||||
if is_cross:
|
if is_cross:
|
||||||
self.add_cross_stdlib_info(target)
|
self.add_cross_stdlib_info(target)
|
||||||
l = targetholder(target, self)
|
l = targetholder(target, self)
|
||||||
|
|
|
@ -105,26 +105,24 @@ class DependenciesHelper:
|
||||||
if obj.found():
|
if obj.found():
|
||||||
processed_libs += obj.get_link_args()
|
processed_libs += obj.get_link_args()
|
||||||
processed_cflags += obj.get_compile_args()
|
processed_cflags += obj.get_compile_args()
|
||||||
elif isinstance(obj, build.SharedLibrary):
|
elif isinstance(obj, build.SharedLibrary) and obj.shared_library_only:
|
||||||
|
# Do not pull dependencies for shared libraries because they are
|
||||||
|
# only required for static linking. Adding private requires has
|
||||||
|
# the side effect of exposing their cflags, which is the
|
||||||
|
# intended behaviour of pkg-config but force Debian to add more
|
||||||
|
# than needed build deps.
|
||||||
|
# See https://bugs.freedesktop.org/show_bug.cgi?id=105572
|
||||||
processed_libs.append(obj)
|
processed_libs.append(obj)
|
||||||
if public:
|
if public:
|
||||||
if not hasattr(obj, 'generated_pc'):
|
if not hasattr(obj, 'generated_pc'):
|
||||||
obj.generated_pc = self.name
|
obj.generated_pc = self.name
|
||||||
elif isinstance(obj, build.StaticLibrary):
|
elif isinstance(obj, (build.SharedLibrary, build.StaticLibrary)):
|
||||||
# Due to a "feature" in pkgconfig, it leaks out private dependencies.
|
|
||||||
# Thus we will not add them to the pc file unless the target
|
|
||||||
# we are processing is a static library.
|
|
||||||
#
|
|
||||||
# This way (hopefully) "pkgconfig --libs --static foobar" works
|
|
||||||
# and "pkgconfig --cflags/--libs foobar" does not have any trace
|
|
||||||
# of dependencies that the build file creator has not explicitly
|
|
||||||
# added to the dependency list.
|
|
||||||
processed_libs.append(obj)
|
processed_libs.append(obj)
|
||||||
if public:
|
|
||||||
if not hasattr(obj, 'generated_pc'):
|
|
||||||
obj.generated_pc = self.name
|
|
||||||
self.add_priv_libs(obj.get_dependencies())
|
self.add_priv_libs(obj.get_dependencies())
|
||||||
self.add_priv_libs(obj.get_external_deps())
|
self.add_priv_libs(obj.get_external_deps())
|
||||||
|
if public:
|
||||||
|
if not hasattr(obj, 'generated_pc'):
|
||||||
|
obj.generated_pc = self.name
|
||||||
elif isinstance(obj, str):
|
elif isinstance(obj, str):
|
||||||
processed_libs.append(obj)
|
processed_libs.append(obj)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -19,10 +19,7 @@ from . import ExtensionModule
|
||||||
from mesonbuild.modules import ModuleReturnValue
|
from mesonbuild.modules import ModuleReturnValue
|
||||||
from . import permittedSnippetKwargs
|
from . import permittedSnippetKwargs
|
||||||
from ..interpreterbase import noKwargs
|
from ..interpreterbase import noKwargs
|
||||||
from ..interpreter import shlib_kwargs
|
from ..build import known_shmod_kwargs
|
||||||
|
|
||||||
mod_kwargs = set()
|
|
||||||
mod_kwargs.update(shlib_kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class Python3Module(ExtensionModule):
|
class Python3Module(ExtensionModule):
|
||||||
|
@ -30,7 +27,7 @@ class Python3Module(ExtensionModule):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.snippets.add('extension_module')
|
self.snippets.add('extension_module')
|
||||||
|
|
||||||
@permittedSnippetKwargs(mod_kwargs)
|
@permittedSnippetKwargs(known_shmod_kwargs)
|
||||||
def extension_module(self, interpreter, state, args, kwargs):
|
def extension_module(self, interpreter, state, args, kwargs):
|
||||||
if 'name_prefix' in kwargs:
|
if 'name_prefix' in kwargs:
|
||||||
raise mesonlib.MesonException('Name_prefix is set automatically, specifying it is forbidden.')
|
raise mesonlib.MesonException('Name_prefix is set automatically, specifying it is forbidden.')
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
DO_EXPORT int retval = 42;
|
||||||
|
|
||||||
|
DO_EXPORT int func() {
|
||||||
|
return retval;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
DO_IMPORT int func();
|
||||||
|
DO_IMPORT int retval;
|
||||||
|
|
||||||
|
int main(int argc, char **arg) {
|
||||||
|
return func() == retval ? 0 : 1;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
project('both libraries linking test', 'c')
|
||||||
|
|
||||||
|
both_libs = both_libraries('mylib', 'libfile.c')
|
||||||
|
exe_shared = executable('prog-shared', 'main.c', link_with : both_libs.get_shared_lib())
|
||||||
|
exe_static = executable('prog-static', 'main.c',
|
||||||
|
c_args : ['-DSTATIC_COMPILATION'],
|
||||||
|
link_with : both_libs.get_static_lib())
|
||||||
|
exe_both = executable('prog-both', 'main.c', link_with : both_libs)
|
||||||
|
|
||||||
|
test('runtest-shared', exe_shared)
|
||||||
|
test('runtest-static', exe_static)
|
||||||
|
test('runtest-both', exe_both)
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef STATIC_COMPILATION
|
||||||
|
#define DO_IMPORT extern
|
||||||
|
#else
|
||||||
|
#define DO_IMPORT __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#define DO_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define DO_IMPORT extern
|
||||||
|
#define DO_EXPORT
|
||||||
|
#endif
|
Loading…
Reference in New Issue