[DOC] Documentation of mkmf.rb
This commit is contained in:
parent
ad7aee35e4
commit
bca1493815
118
lib/mkmf.rb
118
lib/mkmf.rb
@ -59,6 +59,9 @@ module MakeMakefile
|
|||||||
# The makefile configuration using the defaults from when Ruby was built.
|
# The makefile configuration using the defaults from when Ruby was built.
|
||||||
|
|
||||||
CONFIG = RbConfig::MAKEFILE_CONFIG
|
CONFIG = RbConfig::MAKEFILE_CONFIG
|
||||||
|
|
||||||
|
##
|
||||||
|
# The saved original value of +LIB+ environment variable
|
||||||
ORIG_LIBPATH = ENV['LIB']
|
ORIG_LIBPATH = ENV['LIB']
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -245,12 +248,16 @@ MESSAGE
|
|||||||
CSRCFLAG = CONFIG['CSRCFLAG']
|
CSRCFLAG = CONFIG['CSRCFLAG']
|
||||||
CPPOUTFILE = config_string('CPPOUTFILE') {|str| str.sub(/\bconftest\b/, CONFTEST)}
|
CPPOUTFILE = config_string('CPPOUTFILE') {|str| str.sub(/\bconftest\b/, CONFTEST)}
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
|
|
||||||
|
# Removes _files_.
|
||||||
def rm_f(*files)
|
def rm_f(*files)
|
||||||
opt = (Hash === files.last ? [files.pop] : [])
|
opt = (Hash === files.last ? [files.pop] : [])
|
||||||
FileUtils.rm_f(Dir[*files.flatten], *opt)
|
FileUtils.rm_f(Dir[*files.flatten], *opt)
|
||||||
end
|
end
|
||||||
module_function :rm_f
|
module_function :rm_f
|
||||||
|
|
||||||
|
# Removes _files_ recursively.
|
||||||
def rm_rf(*files)
|
def rm_rf(*files)
|
||||||
opt = (Hash === files.last ? [files.pop] : [])
|
opt = (Hash === files.last ? [files.pop] : [])
|
||||||
FileUtils.rm_rf(Dir[*files.flatten], *opt)
|
FileUtils.rm_rf(Dir[*files.flatten], *opt)
|
||||||
@ -265,6 +272,8 @@ MESSAGE
|
|||||||
t if times.all? {|n| n <= t}
|
t if times.all? {|n| n <= t}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :stopdoc:
|
||||||
|
|
||||||
def split_libs(*strs)
|
def split_libs(*strs)
|
||||||
sep = $mswin ? /\s+/ : /\s+(?=-|\z)/
|
sep = $mswin ? /\s+/ : /\s+(?=-|\z)/
|
||||||
strs.flat_map {|s| s.lstrip.split(sep)}
|
strs.flat_map {|s| s.lstrip.split(sep)}
|
||||||
@ -397,6 +406,14 @@ MESSAGE
|
|||||||
envs.map {|e, v| "#{e}=#{v.quote}"}
|
envs.map {|e, v| "#{e}=#{v.quote}"}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
|
|
||||||
|
# call-seq:
|
||||||
|
# xsystem(command, werror: false, **opts) -> true or false
|
||||||
|
#
|
||||||
|
# Executes _command_ with expanding variables, and returns the exit
|
||||||
|
# status like as Kernel#system. If _werror_ is true and the error
|
||||||
|
# output is not empty, returns +false+. The output will logged.
|
||||||
def xsystem command, opts = nil
|
def xsystem command, opts = nil
|
||||||
env, command = expand_command(command)
|
env, command = expand_command(command)
|
||||||
Logging::open do
|
Logging::open do
|
||||||
@ -415,6 +432,7 @@ MESSAGE
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Executes _command_ similarly to xsystem, but yields opened pipe.
|
||||||
def xpopen command, *mode, &block
|
def xpopen command, *mode, &block
|
||||||
env, commands = expand_command(command)
|
env, commands = expand_command(command)
|
||||||
command = [env_quote(env), command].join(' ')
|
command = [env_quote(env), command].join(' ')
|
||||||
@ -429,6 +447,7 @@ MESSAGE
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Logs _src_
|
||||||
def log_src(src, heading="checked program was")
|
def log_src(src, heading="checked program was")
|
||||||
src = src.split(/^/)
|
src = src.split(/^/)
|
||||||
fmt = "%#{src.size.to_s.size}d: %s"
|
fmt = "%#{src.size.to_s.size}d: %s"
|
||||||
@ -443,10 +462,15 @@ EOM
|
|||||||
EOM
|
EOM
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns the language-dependent source file name for configuration
|
||||||
|
# checks.
|
||||||
def conftest_source
|
def conftest_source
|
||||||
CONFTEST_C
|
CONFTEST_C
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Creats temporary source file from +COMMON_HEADERS+ and _src_.
|
||||||
|
# Yields the created source string and uses the returned string as
|
||||||
|
# the source code, if the block is given.
|
||||||
def create_tmpsrc(src)
|
def create_tmpsrc(src)
|
||||||
src = "#{COMMON_HEADERS}\n#{src}"
|
src = "#{COMMON_HEADERS}\n#{src}"
|
||||||
src = yield(src) if block_given?
|
src = yield(src) if block_given?
|
||||||
@ -467,6 +491,8 @@ EOM
|
|||||||
src
|
src
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :stopdoc:
|
||||||
|
|
||||||
def have_devel?
|
def have_devel?
|
||||||
unless defined? $have_devel
|
unless defined? $have_devel
|
||||||
$have_devel = true
|
$have_devel = true
|
||||||
@ -579,8 +605,8 @@ MSG
|
|||||||
|
|
||||||
# Returns whether or not the +src+ can be compiled as a C source and linked
|
# Returns whether or not the +src+ can be compiled as a C source and linked
|
||||||
# with its depending libraries successfully. +opt+ is passed to the linker
|
# with its depending libraries successfully. +opt+ is passed to the linker
|
||||||
# as options. Note that +$CFLAGS+ and +$LDFLAGS+ are also passed to the
|
# as options. Note that <tt>$CFLAGS</tt> and <tt>$LDFLAGS</tt> are also
|
||||||
# linker.
|
# passed to the linker.
|
||||||
#
|
#
|
||||||
# If a block given, it is called with the source before compilation. You can
|
# If a block given, it is called with the source before compilation. You can
|
||||||
# modify the source in the block.
|
# modify the source in the block.
|
||||||
@ -594,8 +620,8 @@ MSG
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Returns whether or not the +src+ can be compiled as a C source. +opt+ is
|
# Returns whether or not the +src+ can be compiled as a C source. +opt+ is
|
||||||
# passed to the C compiler as options. Note that +$CFLAGS+ is also passed to
|
# passed to the C compiler as options. Note that <tt>$CFLAGS</tt> is also
|
||||||
# the compiler.
|
# passed to the compiler.
|
||||||
#
|
#
|
||||||
# If a block given, it is called with the source before compilation. You can
|
# If a block given, it is called with the source before compilation. You can
|
||||||
# modify the source in the block.
|
# modify the source in the block.
|
||||||
@ -611,7 +637,7 @@ MSG
|
|||||||
|
|
||||||
# Returns whether or not the +src+ can be preprocessed with the C
|
# Returns whether or not the +src+ can be preprocessed with the C
|
||||||
# preprocessor. +opt+ is passed to the preprocessor as options. Note that
|
# preprocessor. +opt+ is passed to the preprocessor as options. Note that
|
||||||
# +$CFLAGS+ is also passed to the preprocessor.
|
# <tt>$CFLAGS</tt> is also passed to the preprocessor.
|
||||||
#
|
#
|
||||||
# If a block given, it is called with the source before preprocessing. You
|
# If a block given, it is called with the source before preprocessing. You
|
||||||
# can modify the source in the block.
|
# can modify the source in the block.
|
||||||
@ -636,6 +662,14 @@ MSG
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
|
|
||||||
|
# Sets <tt>$CPPFLAGS</tt> to _flags_ and yields. If the block returns a
|
||||||
|
# falsy value, <tt>$CPPFLAGS</tt> is reset to its previous value, remains
|
||||||
|
# set to _flags_ otherwise.
|
||||||
|
#
|
||||||
|
# [+flags+] a C preprocessor flag as a +String+
|
||||||
|
#
|
||||||
def with_cppflags(flags)
|
def with_cppflags(flags)
|
||||||
cppflags = $CPPFLAGS
|
cppflags = $CPPFLAGS
|
||||||
$CPPFLAGS = flags.dup
|
$CPPFLAGS = flags.dup
|
||||||
@ -644,10 +678,16 @@ MSG
|
|||||||
$CPPFLAGS = cppflags unless ret
|
$CPPFLAGS = cppflags unless ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :nodoc:
|
||||||
def try_cppflags(flags, opts = {})
|
def try_cppflags(flags, opts = {})
|
||||||
try_header(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
|
try_header(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Check whether each given C preprocessor flag is acceptable and append it
|
||||||
|
# to <tt>$CPPFLAGS</tt> if so.
|
||||||
|
#
|
||||||
|
# [+flags+] a C preprocessor flag as a +String+ or an +Array+ of them
|
||||||
|
#
|
||||||
def append_cppflags(flags, *opts)
|
def append_cppflags(flags, *opts)
|
||||||
Array(flags).each do |flag|
|
Array(flags).each do |flag|
|
||||||
if checking_for("whether #{flag} is accepted as CPPFLAGS") {
|
if checking_for("whether #{flag} is accepted as CPPFLAGS") {
|
||||||
@ -658,6 +698,9 @@ MSG
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets <tt>$CFLAGS</tt> to _flags_ and yields. If the block returns a falsy
|
||||||
|
# value, <tt>$CFLAGS</tt> is reset to its previous value, remains set to
|
||||||
|
# _flags_ otherwise.
|
||||||
def with_cflags(flags)
|
def with_cflags(flags)
|
||||||
cflags = $CFLAGS
|
cflags = $CFLAGS
|
||||||
$CFLAGS = flags.dup
|
$CFLAGS = flags.dup
|
||||||
@ -666,10 +709,14 @@ MSG
|
|||||||
$CFLAGS = cflags unless ret
|
$CFLAGS = cflags unless ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :nodoc:
|
||||||
def try_cflags(flags, opts = {})
|
def try_cflags(flags, opts = {})
|
||||||
try_compile(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
|
try_compile(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets <tt>$LDFLAGS</tt> to _flags_ and yields. If the block returns a
|
||||||
|
# falsy value, <tt>$LDFLAGS</tt> is reset to its previous value, remains set
|
||||||
|
# to _flags_ otherwise.
|
||||||
def with_ldflags(flags)
|
def with_ldflags(flags)
|
||||||
ldflags = $LDFLAGS
|
ldflags = $LDFLAGS
|
||||||
$LDFLAGS = flags.dup
|
$LDFLAGS = flags.dup
|
||||||
@ -678,11 +725,19 @@ MSG
|
|||||||
$LDFLAGS = ldflags unless ret
|
$LDFLAGS = ldflags unless ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :nodoc:
|
||||||
def try_ldflags(flags, opts = {})
|
def try_ldflags(flags, opts = {})
|
||||||
opts = {:werror => true}.update(opts) if $mswin
|
opts = {:werror => true}.update(opts) if $mswin
|
||||||
try_link(MAIN_DOES_NOTHING, flags, opts)
|
try_link(MAIN_DOES_NOTHING, flags, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
|
|
||||||
|
# Check whether each given linker flag is acceptable and append it to
|
||||||
|
# <tt>$LDFLAGS</tt> if so.
|
||||||
|
#
|
||||||
|
# [+flags+] a linker flag as a +String+ or an +Array+ of them
|
||||||
|
#
|
||||||
def append_ldflags(flags, *opts)
|
def append_ldflags(flags, *opts)
|
||||||
Array(flags).each do |flag|
|
Array(flags).each do |flag|
|
||||||
if checking_for("whether #{flag} is accepted as LDFLAGS") {
|
if checking_for("whether #{flag} is accepted as LDFLAGS") {
|
||||||
@ -693,6 +748,8 @@ MSG
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :stopdoc:
|
||||||
|
|
||||||
def try_static_assert(expr, headers = nil, opt = "", &b)
|
def try_static_assert(expr, headers = nil, opt = "", &b)
|
||||||
headers = cpp_include(headers)
|
headers = cpp_include(headers)
|
||||||
try_compile(<<SRC, opt, &b)
|
try_compile(<<SRC, opt, &b)
|
||||||
@ -828,6 +885,8 @@ int t(void) { const volatile void *volatile p; p = &(&#{var})[0]; return !p; }
|
|||||||
SRC
|
SRC
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
|
|
||||||
# Returns whether or not the +src+ can be preprocessed with the C
|
# Returns whether or not the +src+ can be preprocessed with the C
|
||||||
# preprocessor and matches with +pat+.
|
# preprocessor and matches with +pat+.
|
||||||
#
|
#
|
||||||
@ -866,6 +925,8 @@ SRC
|
|||||||
log_src(src)
|
log_src(src)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :stopdoc:
|
||||||
|
|
||||||
# This is used internally by the have_macro? method.
|
# This is used internally by the have_macro? method.
|
||||||
def macro_defined?(macro, src, opt = "", &b)
|
def macro_defined?(macro, src, opt = "", &b)
|
||||||
src = src.sub(/[^\n]\z/, "\\&\n")
|
src = src.sub(/[^\n]\z/, "\\&\n")
|
||||||
@ -885,8 +946,8 @@ SRC
|
|||||||
# * the linked file can be invoked as an executable
|
# * the linked file can be invoked as an executable
|
||||||
# * and the executable exits successfully
|
# * and the executable exits successfully
|
||||||
#
|
#
|
||||||
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and
|
# +opt+ is passed to the linker as options. Note that <tt>$CFLAGS</tt> and
|
||||||
# +$LDFLAGS+ are also passed to the linker.
|
# <tt>$LDFLAGS</tt> are also passed to the linker.
|
||||||
#
|
#
|
||||||
# If a block given, it is called with the source before compilation. You can
|
# If a block given, it is called with the source before compilation. You can
|
||||||
# modify the source in the block.
|
# modify the source in the block.
|
||||||
@ -958,6 +1019,10 @@ SRC
|
|||||||
format(LIBARG, lib) + " " + libs
|
format(LIBARG, lib) + " " + libs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Prints messages to $stdout, if verbose mode.
|
||||||
|
#
|
||||||
|
# Internal use only.
|
||||||
|
#
|
||||||
def message(*s)
|
def message(*s)
|
||||||
unless Logging.quiet and not $VERBOSE
|
unless Logging.quiet and not $VERBOSE
|
||||||
printf(*s)
|
printf(*s)
|
||||||
@ -989,6 +1054,10 @@ SRC
|
|||||||
r
|
r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Build a message for checking.
|
||||||
|
#
|
||||||
|
# Internal use only.
|
||||||
|
#
|
||||||
def checking_message(target, place = nil, opt = nil)
|
def checking_message(target, place = nil, opt = nil)
|
||||||
[["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
|
[["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
|
||||||
if noun
|
if noun
|
||||||
@ -1250,6 +1319,7 @@ SRC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :nodoc:
|
||||||
# Returns whether or not the static type +type+ is defined.
|
# Returns whether or not the static type +type+ is defined.
|
||||||
#
|
#
|
||||||
# See also +have_type+
|
# See also +have_type+
|
||||||
@ -1307,6 +1377,7 @@ SRC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :nodoc:
|
||||||
# Returns whether or not the constant +const+ is defined.
|
# Returns whether or not the constant +const+ is defined.
|
||||||
#
|
#
|
||||||
# See also +have_const+
|
# See also +have_const+
|
||||||
@ -1525,6 +1596,10 @@ SRC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
|
|
||||||
|
# Returns a string represents the type of _type_, or _member_ of
|
||||||
|
# _type_ if _member_ is not +nil+.
|
||||||
def what_type?(type, member = nil, headers = nil, &b)
|
def what_type?(type, member = nil, headers = nil, &b)
|
||||||
m = "#{type}"
|
m = "#{type}"
|
||||||
var = val = "*rbcv_var_"
|
var = val = "*rbcv_var_"
|
||||||
@ -1584,6 +1659,8 @@ SRC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :nodoc:
|
||||||
|
#
|
||||||
# This method is used internally by the find_executable method.
|
# This method is used internally by the find_executable method.
|
||||||
#
|
#
|
||||||
# Internal use only.
|
# Internal use only.
|
||||||
@ -1622,8 +1699,6 @@ SRC
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# :startdoc:
|
|
||||||
|
|
||||||
# Searches for the executable +bin+ on +path+. The default path is your
|
# Searches for the executable +bin+ on +path+. The default path is your
|
||||||
# +PATH+ environment variable. If that isn't defined, it will resort to
|
# +PATH+ environment variable. If that isn't defined, it will resort to
|
||||||
# searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
|
# searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
|
||||||
@ -2727,6 +2802,9 @@ MESSAGE
|
|||||||
|
|
||||||
split = Shellwords.method(:shellwords).to_proc
|
split = Shellwords.method(:shellwords).to_proc
|
||||||
|
|
||||||
|
##
|
||||||
|
# The prefix added to exported symbols automatically
|
||||||
|
|
||||||
EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
|
EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
|
||||||
|
|
||||||
hdr = ['#include "ruby.h"' "\n"]
|
hdr = ['#include "ruby.h"' "\n"]
|
||||||
@ -2756,6 +2834,10 @@ MESSAGE
|
|||||||
# make compile rules
|
# make compile rules
|
||||||
|
|
||||||
COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
|
COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
|
||||||
|
|
||||||
|
##
|
||||||
|
# Substitution in rules for NMake
|
||||||
|
|
||||||
RULE_SUBST = config_string('RULE_SUBST')
|
RULE_SUBST = config_string('RULE_SUBST')
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -2801,6 +2883,10 @@ MESSAGE
|
|||||||
# Argument which will add a library path to the linker
|
# Argument which will add a library path to the linker
|
||||||
|
|
||||||
LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L%s'
|
LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L%s'
|
||||||
|
|
||||||
|
##
|
||||||
|
# Argument which will add a runtime library path to the linker
|
||||||
|
|
||||||
RPATHFLAG = config_string('RPATHFLAG') || ''
|
RPATHFLAG = config_string('RPATHFLAG') || ''
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -2812,6 +2898,10 @@ MESSAGE
|
|||||||
# A C main function which does no work
|
# A C main function which does no work
|
||||||
|
|
||||||
MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return !!argv[argc];\n}"
|
MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return !!argv[argc];\n}"
|
||||||
|
|
||||||
|
##
|
||||||
|
# The type names for convertible_int
|
||||||
|
|
||||||
UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
|
UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
|
||||||
%w[int short long long\ long]
|
%w[int short long long\ long]
|
||||||
|
|
||||||
@ -2842,18 +2932,26 @@ realclean: distclean
|
|||||||
|
|
||||||
@lang = Hash.new(self)
|
@lang = Hash.new(self)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Retrieves the module for _name_ language.
|
||||||
def self.[](name)
|
def self.[](name)
|
||||||
@lang.fetch(name)
|
@lang.fetch(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Defines the module for _name_ language.
|
||||||
def self.[]=(name, mod)
|
def self.[]=(name, mod)
|
||||||
@lang[name] = mod
|
@lang[name] = mod
|
||||||
end
|
end
|
||||||
|
|
||||||
self["C++"] = Module.new do
|
self["C++"] = Module.new do
|
||||||
|
# Module for C++
|
||||||
|
|
||||||
include MakeMakefile
|
include MakeMakefile
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
|
# :stopdoc:
|
||||||
|
|
||||||
CONFTEST_CXX = "#{CONFTEST}.#{config_string('CXX_EXT') || CXX_EXT[0]}"
|
CONFTEST_CXX = "#{CONFTEST}.#{config_string('CXX_EXT') || CXX_EXT[0]}"
|
||||||
|
|
||||||
TRY_LINK_CXX = config_string('TRY_LINK_CXX') ||
|
TRY_LINK_CXX = config_string('TRY_LINK_CXX') ||
|
||||||
@ -2883,6 +2981,8 @@ realclean: distclean
|
|||||||
conf = link_config(ldflags, *opts)
|
conf = link_config(ldflags, *opts)
|
||||||
RbConfig::expand(TRY_LINK_CXX.dup, conf)
|
RbConfig::expand(TRY_LINK_CXX.dup, conf)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :startdoc:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user