Modul MakeMakefile
Das Modul MakeMakefile wird von Ruby C-Erweiterungen verwendet, um ein Makefile zu generieren, das die C-Erweiterung korrekt kompiliert und mit Ruby sowie einer Drittanbieterbibliothek verknüpft.
Constants
- ASSEMBLE_C
-
Befehl, der C-Dateien in Assembler-Quellen im generierten Makefile übersetzt
- ASSEMBLE_CXX
-
Befehl, der C++-Dateien in Assembler-Quellen im generierten Makefile übersetzt
- CLEANINGS
-
Makefile-Regeln, die das Build-Verzeichnis der Erweiterung bereinigen
- COMMON_HEADERS
-
Gemeinsame Header für Ruby C-Erweiterungen
- COMMON_LIBS
-
Gemeinsame Bibliotheken für Ruby C-Erweiterungen
- COMPILE_C
-
Befehl, der C-Dateien im generierten Makefile kompiliert
- COMPILE_CXX
-
Befehl, der C++-Dateien im generierten Makefile kompiliert
- COMPILE_RULES
-
make Compile-Regeln
- CONFIG
-
Die Makefile-Konfiguration mit den Standardwerten von der Erstellung von Ruby.
- CXX_EXT
-
Erweiterungen für Dateien, die mit einem C++-Compiler kompiliert werden
- C_EXT
-
Erweiterungen für Dateien, die mit einem C-Compiler kompiliert werden
- EXPORT_PREFIX
-
Das Präfix, das automatisch an exportierte Symbole angehängt wird
- HDR_EXT
-
Erweiterungen für Header-Dateien
- LANGUAGE
-
Die Sprache, für die dieses Modul bestimmt ist
- LIBARG
-
Argument, das eine Bibliothek zum Linker hinzufügt
- LIBPATHFLAG
-
Argument, das einen Bibliotheks-Pfad zum Linker hinzufügt
- LINK_SO
-
Befehl, der eine gemeinsam genutzte Bibliothek verknüpft
- MAIN_DOES_NOTHING
-
Eine C-main-Funktion, die keine Arbeit verrichtet
- ORIG_LIBPATH
-
Der gespeicherte Originalwert der Umgebungsvariablen
LIB - RPATHFLAG
-
Argument, das einen Laufzeitbibliotheks-Pfad zum Linker hinzufügt
- RULE_SUBST
-
Substitution in Regeln für NMake
- RbConfig
-
Das Modul, das Ruby-Interpreter-Konfigurationen beim Erstellen speichert.
Diese Datei wurde von mkconfig.rb beim Erstellen von Ruby erstellt. Sie enthält Build-Informationen für Ruby, die z. B. von mkmf verwendet werden, um kompatible native Erweiterungen zu erstellen. Alle Änderungen an dieser Datei gehen beim nächsten Erstellen von Ruby verloren.
- SRC_EXT
-
Erweiterungen für Quelldateien
- TRY_LINK
-
Befehl, der ein Programm kompiliert, um das Verknüpfen einer Bibliothek zu testen
- UNIVERSAL_INTS
-
Die Typnamen für
convertible_int
Öffentliche Klassenmethoden
Source
# File lib/mkmf.rb, line 2990 def self.[](name) @lang.fetch(name) end
Ruft das Modul für die Sprache name ab.
Source
# File lib/mkmf.rb, line 2996 def self.[]=(name, mod) @lang[name] = mod end
Definiert das Modul für die Sprache name.
Source
# File lib/mkmf.rb, line 270 def rm_f(*files) opt = (Hash === files.last ? [files.pop] : []) FileUtils.rm_f(Dir[*files.flatten], *opt) end
Entfernt die Dateien.
Source
# File lib/mkmf.rb, line 277 def rm_rf(*files) opt = (Hash === files.last ? [files.pop] : []) FileUtils.rm_rf(Dir[*files.flatten], *opt) end
Entfernt die Dateien rekursiv.
Öffentliche Instanzmethoden
Source
# File lib/mkmf.rb, line 1106 def append_cflags(flags, **opts) Array(flags).each do |flag| if checking_for("whether #{flag} is accepted as CFLAGS") { try_cflags(flag, **opts) } $CFLAGS << " " << flag end end end
Source
# File lib/mkmf.rb, line 762 def append_ldflags(flags, **opts) Array(flags).each do |flag| if checking_for("whether #{flag} is accepted as LDFLAGS") { try_ldflags(flag, **opts) } $LDFLAGS << " " << flag end end end
Source
# File lib/mkmf.rb, line 1509 def check_signedness(type, headers = nil, opts = nil, &b) typedef, member, prelude = typedef_expr(type, headers) signed = nil checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do signed = try_signedness(typedef, member, [prelude], opts, &b) or next nil $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed]) signed < 0 ? "signed" : "unsigned" end signed end
Gibt die Vorzeichenbehaftung des gegebenen type zurück. Sie können optional zusätzliche headers angeben, in denen nach dem type gesucht werden soll.
Wenn der type gefunden wird und ein numerischer Typ ist, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der type-Name in Großbuchstaben verwendet wird, dem SIGNEDNESS_OF_ vorangestellt ist, gefolgt vom type-Namen, gefolgt von =X, wobei „X“ eine positive Ganzzahl ist, wenn der type vorzeichenlos ist, und eine negative Ganzzahl, wenn der type vorzeichenbehaftet ist.
Wenn beispielsweise size_t als vorzeichenlos definiert ist, gibt check_signedness('size_t') +1 zurück und das Präprozessormakro SIGNEDNESS_OF_SIZE_T=+1 wird an den Compiler übergeben. Das Makro SIGNEDNESS_OF_INT=-1 wird für check_signedness('int') gesetzt.
Source
# File lib/mkmf.rb, line 1480 def check_sizeof(type, headers = nil, opts = "", &b) typedef, member, prelude = typedef_expr(type, headers) prelude << "#{typedef} *rbcv_ptr_;\n" prelude = [prelude] expr = "sizeof((*rbcv_ptr_)#{"." << member if member})" fmt = STRING_OR_FAILED_FORMAT checking_for checking_message("size of #{type}", headers), fmt do if size = try_constant(expr, prelude, opts, &b) $defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size)) size end end end
Gibt die Größe des gegebenen type zurück. Sie können optional zusätzliche headers angeben, in denen nach dem type gesucht werden soll.
Wenn gefunden, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der Typname in Großbuchstaben verwendet wird, dem SIZEOF_ vorangestellt ist, gefolgt vom Typnamen und =X, wobei „X“ die tatsächliche Größe ist.
Wenn beispielsweise check_sizeof('mystruct') 12 zurückgibt, wird das Präprozessormakro SIZEOF_MYSTRUCT=12 an den Compiler übergeben.
Source
# File lib/mkmf.rb, line 488 def conftest_source CONFTEST_C end
Gibt den sprachabhängigen Quelldateinamen für Konfigurationsprüfungen zurück.
Source
# File lib/mkmf.rb, line 1544 def convertible_int(type, headers = nil, opts = nil, &b) type, macname = *type checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do if UNIVERSAL_INTS.include?(type) type else typedef, member, prelude = typedef_expr(type, headers, &b) if member prelude << "static rbcv_typedef_ rbcv_var;" compat = UNIVERSAL_INTS.find {|t| try_static_assert("sizeof(rbcv_var.#{member}) == sizeof(#{t})", [prelude], opts, &b) } else next unless signed = try_signedness(typedef, member, [prelude]) u = "unsigned " if signed > 0 prelude << "extern rbcv_typedef_ foo();" compat = UNIVERSAL_INTS.find {|t| try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, werror: true, &b) } end if compat macname ||= type.sub(/_(?=t\z)/, '').tr_cpp conv = (compat == "long long" ? "LL" : compat.upcase) compat = "#{u}#{compat}" typename = type.tr_cpp $defs.push(format("-DSIZEOF_%s=SIZEOF_%s", typename, compat.tr_cpp)) $defs.push(format("-DTYPEOF_%s=%s", typename, compat.quote)) $defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv)) conv = (u ? "U" : "") + conv $defs.push(format("-D%s2NUM=%s2NUM", macname, conv)) $defs.push(format("-DNUM2%s=NUM2%s", macname, conv)) compat end end end end
Gibt den konvertierbaren Ganzzahltyp des gegebenen type zurück. Sie können optional zusätzliche headers angeben, in denen nach dem type gesucht werden soll. *konvertierbar* bedeutet tatsächlich derselbe Typ oder ein Typedef von demselben Typ.
Wenn der type ein Ganzzahltyp ist und der *konvertierbare* Typ gefunden wird, werden die folgenden Makros als Präprozessorkonstanten an den Compiler übergeben, wobei der type-Name in Großbuchstaben verwendet wird.
-
TYPEOF_, gefolgt vomtype-Namen, gefolgt von=X, wobei „X“ der gefundene *konvertierbare* Typname ist. -
TYP2NUMundNUM2TYP, wobeiTYPdertype-Name in Großbuchstaben ist, wobei ein Suffix_tdurch „T“ ersetzt wird, gefolgt von=X, wobei „X“ der Makroname ist, um dentypein einInteger-Objekt zu konvertieren und umgekehrt.
Wenn beispielsweise foobar_t als unsigned long definiert ist, gibt convertible_int("foobar_t") „unsigned long“ zurück und definiert diese Makros
#define TYPEOF_FOOBAR_T unsigned long #define FOOBART2NUM ULONG2NUM #define NUM2FOOBART NUM2ULONG
Source
# File lib/mkmf.rb, line 1840 def create_header(header = "extconf.h") message "creating %s\n", header sym = header.tr_cpp hdr = ["#ifndef #{sym}\n#define #{sym}\n"] for line in $defs case line when /^-D([^=]+)(?:=(.*))?/ hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n" when /^-U(.*)/ hdr << "#undef #$1\n" end end hdr << "#endif\n" hdr = hdr.join("") log_src(hdr, "#{header} is") unless (File.read(header) == hdr rescue false) File.open(header, "wb") do |hfile| hfile.write(hdr) end end $extconf_h = header end
Generiert eine Header-Datei, die aus den verschiedenen Makrodefinitionen besteht, die von anderen Methoden wie have_func und have_header generiert wurden. Diese werden in eine benutzerdefinierte ifndef basierend auf dem header-Dateinamen eingepackt, der standardmäßig „extconf.h“ ist.
Zum Beispiel
# extconf.rb require 'mkmf' have_func('realpath') have_header('sys/utime.h') create_header create_makefile('foo')
Das obige Skript würde die folgende extconf.h-Datei generieren
#ifndef EXTCONF_H #define EXTCONF_H #define HAVE_REALPATH 1 #define HAVE_SYS_UTIME_H 1 #endif
Da die Methode create_header eine Datei basierend auf zuvor in Ihrer extconf.rb-Datei festgelegten Definitionen generiert, möchten Sie diese wahrscheinlich als eine der letzten Methoden aufrufen, die Sie in Ihrem Skript aufrufen.
Source
# File lib/mkmf.rb, line 2396 def create_makefile(target, srcprefix = nil) $target = target libpath = $DEFLIBPATH|$LIBPATH message "creating Makefile\n" MakeMakefile.rm_f "#{CONFTEST}*" if CONFIG["DLEXT"] == $OBJEXT for lib in libs = $libs.split(' ') lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%) end $defs.push(format("-DEXTLIB='%s'", libs.join(","))) end if target.include?('/') target_prefix, target = File.split(target) target_prefix[0,0] = '/' else target_prefix = "" end srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/') RbConfig.expand(srcdir = srcprefix.dup) ext = ".#{$OBJEXT}" orig_srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] if not $objs srcs = $srcs || orig_srcs $objs = [] objs = srcs.inject(Hash.new {[]}) {|h, f| h.key?(o = File.basename(f, ".*") << ext) or $objs << o h[o] <<= f h } unless objs.delete_if {|b, f| f.size == 1}.empty? dups = objs.map {|b, f| "#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}" } abort "source files duplication - #{dups.join(", ")}" end else $objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o" srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"} end $srcs = srcs hdrs = Dir[File.join(srcdir, "*.{#{HDR_EXT.join(%q{,})}}")] target = nil if $objs.empty? if target and EXPORT_PREFIX if File.exist?(File.join(srcdir, target + '.def')) deffile = "$(srcdir)/$(TARGET).def" unless EXPORT_PREFIX.empty? makedef = %{$(RUBY) -pe "$$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i" #{deffile}} end else makedef = %{(echo EXPORTS && echo $(TARGET_ENTRY))} end if makedef $cleanfiles << '$(DEFFILE)' origdef = deffile deffile = "$(TARGET)-$(arch).def" end end origdef ||= '' if $extout and $INSTALLFILES $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.delete_prefix('./'))}) $distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir}) end if $extmk and $static $defs << "-DRUBY_EXPORT=1" end if $extmk and not $extconf_h create_header end libpath = libpathflag(libpath) dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : "" staticlib = target ? "$(TARGET).#$LIBEXT" : "" conf = configuration(srcprefix) conf << "\ libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")} LIBPATH = #{libpath} DEFFILE = #{deffile} CLEANFILES = #{$cleanfiles.join(' ')} DISTCLEANFILES = #{$distcleanfiles.join(' ')} DISTCLEANDIRS = #{$distcleandirs.join(' ')} extout = #{$extout && $extout.quote} extout_prefix = #{$extout_prefix} target_prefix = #{target_prefix} LOCAL_LIBS = #{$LOCAL_LIBS} LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS} ORIG_SRCS = #{orig_srcs.collect(&File.method(:basename)).join(' ')} SRCS = $(ORIG_SRCS) #{(srcs - orig_srcs).collect(&File.method(:basename)).join(' ')} OBJS = #{$objs.join(" ")} HDRS = #{hdrs.map{|h| '$(srcdir)/' + File.basename(h)}.join(' ')} LOCAL_HDRS = #{$headers.join(' ')} TARGET = #{target} TARGET_NAME = #{target && target[/\A\w+/]} TARGET_ENTRY = #{EXPORT_PREFIX || ''}Init_$(TARGET_NAME) DLLIB = #{dllib} EXTSTATIC = #{$static || ""} STATIC_LIB = #{staticlib unless $static.nil?} #{!$extout && defined?($installed_list) ? %[INSTALLED_LIST = #{$installed_list}\n] : ""} TIMESTAMP_DIR = #{$extout && $extmk ? '$(extout)/.timestamp' : '.'} " #" # TODO: fixme install_dirs.each {|d| conf << ("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]} sodir = $extout ? '$(TARGET_SO_DIR)' : '$(RUBYARCHDIR)' n = '$(TARGET_SO_DIR)$(TARGET)' cleanobjs = ["$(OBJS)"] cleanlibs = [] if $extmk %w[bc i s].each {|ex| cleanobjs << "$(OBJS:.#{$OBJEXT}=.#{ex})"} end if target config_string('cleanobjs') {|t| cleanobjs << t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")} cleanlibs << '$(TARGET_SO)' end config_string('cleanlibs') {|t| cleanlibs << t.gsub(/\$\*/) {n}} conf << "\ TARGET_SO_DIR =#{$extout ? " $(RUBYARCHDIR)/" : ''} TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) CLEANLIBS = #{cleanlibs.join(' ')} CLEANOBJS = #{cleanobjs.join(' ')} *.bak TARGET_SO_DIR_TIMESTAMP = #{timestamp_file(sodir, target_prefix)} " #" conf = yield(conf) if block_given? mfile = File.open("Makefile", "wb") mfile.puts(conf) mfile.print " all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"} static: #{$extmk && !$static ? "all" : %[$(STATIC_LIB)#{$extout ? " install-rb" : ""}]} .PHONY: all install static install-so install-rb .PHONY: clean clean-so clean-static clean-rb " #" mfile.print CLEANINGS fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"} if fsep sep = ":/=#{fsep}" fseprepl = proc {|s| s = s.gsub("/", fsep) s = s.gsub(/(\$\(\w+)(\))/) {$1+sep+$2} s.gsub(/(\$\{\w+)(\})/) {$1+sep+$2} } rsep = ":#{fsep}=/" else fseprepl = proc {|s| s} sep = "" rsep = "" end dirs = [] mfile.print "install: install-so install-rb\n\n" dir = sodir.dup mfile.print("install-so: ") if target f = "$(DLLIB)" dest = "$(TARGET_SO)" stamp = '$(TARGET_SO_DIR_TIMESTAMP)' if $extout mfile.puts dest mfile.print "clean-so::\n" mfile.print "\t-$(Q)$(RM) #{fseprepl[dest]} #{fseprepl[stamp]}\n" mfile.print "\t-$(Q)$(RM_RF) #{fseprepl['$(CLEANLIBS)']}\n" mfile.print "\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n" else mfile.print "#{f} #{stamp}\n" mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n" if defined?($installed_list) mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n" end end mfile.print "clean-static::\n" mfile.print "\t-$(Q)$(RM) $(STATIC_LIB)\n" else mfile.puts "Makefile" end mfile.print("install-rb: pre-install-rb do-install-rb install-rb-default\n") mfile.print("install-rb-default: pre-install-rb-default do-install-rb-default\n") mfile.print("pre-install-rb: Makefile\n") mfile.print("pre-install-rb-default: Makefile\n") mfile.print("do-install-rb:\n") mfile.print("do-install-rb-default:\n") for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]] files = install_files(mfile, i, nil, srcprefix) or next for dir, *files in files unless dirs.include?(dir) dirs << dir mfile.print "pre-install-rb#{sfx}: #{timestamp_file(dir, target_prefix)}\n" end for f in files dest = "#{dir}/#{File.basename(f)}" mfile.print("do-install-rb#{sfx}: #{dest}\n") mfile.print("#{dest}: #{f} #{timestamp_file(dir, target_prefix)}\n") mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $@\n") if defined?($installed_list) and !$extout mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n") end if $extout mfile.print("clean-rb#{sfx}::\n") mfile.print("\t-$(Q)$(RM) #{fseprepl[dest]}\n") end end end mfile.print "pre-install-rb#{sfx}:\n" if files.empty? mfile.print("\t@$(NULLCMD)\n") else q = "$(MAKE) -q do-install-rb#{sfx}" if $nmake mfile.print "!if \"$(Q)\" == \"@\"\n\t@#{q} || \\\n!endif\n\t" else mfile.print "\t$(Q1:0=@#{q} || )" end mfile.print "$(ECHO1:0=echo) installing#{sfx.sub(/^-/, " ")} #{target} libraries\n" end if $extout dirs.uniq! unless dirs.empty? mfile.print("clean-rb#{sfx}::\n") for dir in dirs.sort_by {|d| -d.count('/')} stamp = timestamp_file(dir, target_prefix) mfile.print("\t-$(Q)$(RM) #{fseprepl[stamp]}\n") mfile.print("\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n") end end end end if target and !dirs.include?(sodir) mfile.print "$(TARGET_SO_DIR_TIMESTAMP):\n\t$(Q) $(MAKEDIRS) $(@D) #{sodir}\n\t$(Q) $(TOUCH) $@\n" end dirs.each do |d| t = timestamp_file(d, target_prefix) mfile.print "#{t}:\n\t$(Q) $(MAKEDIRS) $(@D) #{d}\n\t$(Q) $(TOUCH) $@\n" end mfile.print <<-SITEINSTALL site-install: site-install-so site-install-rb site-install-so: install-so site-install-rb: install-rb SITEINSTALL return unless target mfile.print ".SUFFIXES: .#{(SRC_EXT + [$OBJEXT, $ASMEXT]).compact.join(' .')}\n" mfile.print "\n" compile_command = "\n\t$(ECHO) compiling $(<#{rsep})\n\t$(Q) %s\n\n" command = compile_command % COMPILE_CXX asm_command = compile_command.sub(/compiling/, 'translating') % ASSEMBLE_CXX CXX_EXT.each do |e| each_compile_rules do |rule| mfile.printf(rule, e, $OBJEXT) mfile.print(command) mfile.printf(rule, e, $ASMEXT) mfile.print(asm_command) end end command = compile_command % COMPILE_C asm_command = compile_command.sub(/compiling/, 'translating') % ASSEMBLE_C C_EXT.each do |e| each_compile_rules do |rule| mfile.printf(rule, e, $OBJEXT) mfile.print(command) mfile.printf(rule, e, $ASMEXT) mfile.print(asm_command) end end mfile.print "$(TARGET_SO): " mfile.print "$(DEFFILE) " if makedef mfile.print "$(OBJS) Makefile" mfile.print " $(TARGET_SO_DIR_TIMESTAMP)" if $extout mfile.print "\n" mfile.print "\t$(ECHO) linking shared-object #{target_prefix.sub(/\A\/(.*)/, '\1/')}$(DLLIB)\n" mfile.print "\t-$(Q)$(RM) $(@#{sep})\n" link_so = LINK_SO.gsub(/^/, "\t$(Q) ") if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===)) link_so = link_so.sub(/\bLDSHARED\b/, '\&XX') end mfile.print link_so, "\n\n" unless $static.nil? mfile.print "$(STATIC_LIB): $(OBJS)\n\t-$(Q)$(RM) $(@#{sep})\n\t" mfile.print "$(ECHO) linking static-library $(@#{rsep})\n\t$(Q) " mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)" config_string('RANLIB') do |ranlib| mfile.print "\n\t-$(Q)#{ranlib} $(@)#{$ignore_error}" end end mfile.print "\n\n" if makedef mfile.print "$(DEFFILE): #{origdef}\n" mfile.print "\t$(ECHO) generating $(@#{rsep})\n" mfile.print "\t$(Q) #{makedef} > $@\n\n" end depend = File.join(srcdir, "depend") if File.exist?(depend) mfile.print("###\n", *depend_rules(File.read(depend))) else mfile.print "$(OBJS): $(HDRS) $(ruby_headers)\n" end $makefile_created = true ensure mfile.close if mfile end
Generiert das Makefile für Ihre Erweiterung und übergibt alle Optionen und Präprozessorkonstanten weiter, die Sie möglicherweise mit anderen Methoden generiert haben.
Der target-Name sollte dem Namen der globalen Funktion entsprechen, die in Ihrer C-Erweiterung definiert ist, abzüglich Init_. Wenn Ihre C-Erweiterung beispielsweise als Init_foo definiert ist, wäre Ihr Ziel einfach „foo“.
Wenn im Zielnamen „/“-Zeichen vorhanden sind, wird nur der letzte Name als Zielname interpretiert, und der Rest wird als Verzeichnisse der obersten Ebene betrachtet. Das generierte Makefile wird entsprechend geändert, um diese Verzeichnisstruktur zu befolgen.
Wenn Sie beispielsweise „test/foo“ als Zielnamen übergeben, wird Ihre Erweiterung unter dem Verzeichnis „test“ installiert. Das bedeutet, um die Datei später in einem Ruby-Programm zu laden, muss diese Verzeichnisstruktur befolgt werden, z. B. require 'test/foo'.
Der srcprefix sollte verwendet werden, wenn Ihre Quelldateien nicht im selben Verzeichnis wie Ihr Build-Skript liegen. Dies beseitigt nicht nur die Notwendigkeit, die Quelldateien manuell in dasselbe Verzeichnis wie Ihr Build-Skript zu kopieren, sondern legt auch den richtigen target_prefix im generierten Makefile fest.
Das Festlegen von target_prefix installiert die generierte Binärdatei in einem Verzeichnis unter Ihrem RbConfig::CONFIG['sitearchdir'], das Ihrem lokalen Dateisystem nachempfunden ist, wenn Sie make install ausführen.
Beispielsweise mit dem folgenden Dateibaum
ext/ extconf.rb test/ foo.c
Und mit dem folgenden Code
create_makefile('test/foo', 'test')
Dadurch wird der target_prefix im generierten Makefile auf „test“ gesetzt. Dies wiederum erstellt den folgenden Dateibaum, wenn er über den Befehl make install installiert wird
/path/to/ruby/sitearchdir/test/foo.so
Es wird empfohlen, diesen Ansatz zu verwenden, um Ihre Makefiles zu generieren, anstatt Dateien manuell zu kopieren, da einige Drittanbieterbibliotheken davon abhängen können, dass target_prefix richtig gesetzt ist.
Das Argument srcprefix kann verwendet werden, um das Standard-Quellverzeichnis, d. h. das aktuelle Verzeichnis, zu überschreiben. Es ist Teil von VPATH und wird zur Liste von INCFLAGS hinzugefügt.
Gibt den Konfigurationsteil des zu generierenden Makefiles als Array von Strings zurück, wenn der Block gegeben ist. Der zurückgegebene Wert wird für den neuen Konfigurationsteil verwendet.
create_makefile('foo') {|conf| [ *conf, "MACRO_YOU_NEED = something", ] }
Wenn die Datei „depend“ im Quellverzeichnis existiert, wird deren Inhalt in das generierte Makefile aufgenommen und von der Methode depend_rules formatiert.
Source
# File lib/mkmf.rb, line 495 def create_tmpsrc(src) src = "#{COMMON_HEADERS}\n#{src}" src = yield(src) if block_given? src.gsub!(/[ \t]+$/, '') src.gsub!(/\A\n+|^\n+$/, '') src.sub!(/[^\n]\z/, "\\&\n") count = 0 begin File.open(conftest_source, "wb") do |cfile| cfile.print src end rescue Errno::EACCES if (count += 1) < 5 sleep 0.2 retry end end src end
Erstellt eine temporäre Quelldatei aus COMMON_HEADERS und src. Wenn der Block gegeben ist, wird er mit dem erstellten Quellstring aufgerufen. Der zurückgegebene String wird als Quellcode verwendet.
Source
# File lib/mkmf.rb, line 2268 def depend_rules(depend) suffixes = [] depout = [] cont = implicit = nil impconv = proc do each_compile_rules {|rule| depout << (rule % implicit[0]) << implicit[1]} implicit = nil end ruleconv = proc do |line| if implicit if /\A\t/ =~ line implicit[1] << line next else impconv[] end end if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line) suffixes << m[1] << m[2] implicit = [[m[1], m[2]], [m.post_match]] next elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line line.sub!(/\s*\#.*$/, '') comment = $& line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2} line = line.chomp + comment + "\n" if comment end depout << line end depend.each_line do |line| line.gsub!(/\.o\b/, ".#{$OBJEXT}") line.gsub!(/\{\$\(VPATH\)\}/, "") unless $nmake line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")} line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\') end if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line (cont ||= []) << line next elsif cont line = (cont << line).join cont = nil end ruleconv.call(line) end if cont ruleconv.call(cont.join) elsif implicit impconv.call end unless suffixes.empty? depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n") end if $extconf_h depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") depout.unshift("$(OBJS): $(hdrdir)/ruby/win32.h\n\n") if $mswin or $mingw end depout.flatten! depout end
Verarbeitet die Dateninhalte der „depend“-Datei. Jede Zeile dieser Datei wird als Dateiname erwartet.
Gibt die gefundenen Ergebnisse im Makefile-Format zurück.
Source
# File lib/mkmf.rb, line 1890 def dir_config(target, idefault=nil, ldefault=nil) key = [target, idefault, ldefault].compact.join("\0") if conf = $config_dirs[key] return conf end if dir = with_config(target + "-dir", (idefault unless ldefault)) defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR) idefault = ldefault = nil end idir = with_config(target + "-include", idefault) if conf = $arg_config.assoc("--with-#{target}-include") conf[1] ||= "${#{target}-dir}/include" end ldir = with_config(target + "-lib", ldefault) if conf = $arg_config.assoc("--with-#{target}-lib") conf[1] ||= "${#{target}-dir}/#{_libdir_basename}" end idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : [] if defaults idirs.concat(defaults.collect {|d| d + "/include"}) idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR) end unless idirs.empty? idirs.collect! {|d| "-I" + d} idirs -= Shellwords.shellwords($CPPFLAGS) unless idirs.empty? $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ") end end ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : [] if defaults ldirs.concat(defaults.collect {|d| "#{d}/#{_libdir_basename}"}) ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR) end $LIBPATH = ldirs | $LIBPATH $config_dirs[key] = [idir, ldir] end
Legt einen target-Namen fest, den der Benutzer dann verwenden kann, um verschiedene „with“-Optionen über die Befehlszeile zu konfigurieren, indem er diesen Namen verwendet. Wenn beispielsweise das Ziel auf „foo“ gesetzt ist, könnte der Benutzer die Befehlszeilenoptionen --with-foo-dir=prefix, --with-foo-include=dir und --with-foo-lib=dir verwenden, um anzugeben, wo nach Header/Bibliotheksdateien gesucht werden soll.
Sie können zusätzliche Parameter übergeben, um Standardwerte anzugeben. Wenn einer gegeben ist, wird er als Standard-prefix genommen, und wenn zwei gegeben sind, werden sie der Reihe nach als „include“- und „lib“-Standardwerte genommen.
In jedem Fall ist der Rückgabewert ein Array von ermittelten „include“- und „lib“-Verzeichnissen, wobei jedes nil sein kann, wenn keine entsprechende Befehlszeilenoption angegeben ist und kein Standardwert angegeben wurde.
Beachten Sie, dass dir_config nur zur Liste der zu durchsuchenden Bibliotheken und Include-Dateien hinzugefügt wird. Es verknüpft die Bibliotheken nicht mit Ihrer Anwendung.
Source
# File lib/mkmf.rb, line 2237 def dummy_makefile(srcdir) configuration(srcdir) << <<RULES << CLEANINGS CLEANFILES = #{$cleanfiles.join(' ')} DISTCLEANFILES = #{$distcleanfiles.join(' ')} all install static install-so install-rb: Makefile @$(NULLCMD) .PHONY: all install static install-so install-rb .PHONY: clean clean-so clean-static clean-rb RULES end
Erstellt ein Stub-Makefile.
Source
# File lib/mkmf.rb, line 923 def egrep_cpp(pat, src, opt = "", &b) src = create_tmpsrc(src, &b) xpopen(cpp_command('', opt)) do |f| if Regexp === pat puts(" ruby -ne 'print if #{pat.inspect}'") f.grep(pat) {|l| puts "#{f.lineno}: #{l}" return true } false else puts(" egrep '#{pat}'") begin stdin = $stdin.dup $stdin.reopen(f) system("egrep", pat) ensure $stdin.reopen(stdin) end end end ensure MakeMakefile.rm_f "#{CONFTEST}*" log_src(src) end
Gibt zurück, ob src mit dem C-Präprozessor vorverarbeitet werden kann und mit pat übereinstimmt.
Wenn ein Block gegeben ist, wird er mit der Quelle vor der Kompilierung aufgerufen. Sie können die Quelle im Block ändern.
HINWEIS: Wenn pat ein Regexp ist, wird die Übereinstimmung im Prozess überprüft, andernfalls wird egrep(1) aufgerufen, um sie zu überprüfen.
Source
# File lib/mkmf.rb, line 1802 def enable_config(config, default=nil) if arg_config("--enable-"+config) true elsif arg_config("--disable-"+config) false elsif block_given? yield(config, default) else return default end end
Testet auf die Anwesenheit einer --enable-config oder --disable-config Option. Gibt true zurück, wenn die Enable-Option gegeben ist, false, wenn die Disable-Option gegeben ist, und andernfalls den Standardwert.
Dies kann nützlich sein, um benutzerdefinierte Definitionen wie Debug-Informationen hinzuzufügen.
Beispiel
if enable_config("debug") $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG" end
Source
# File lib/mkmf.rb, line 1290 def find_header(header, *paths) message = checking_message(header, paths) header = cpp_include(header) checking_for message do if try_header(header) true else found = false paths.each do |dir| opt = "-I#{dir}".quote if try_header(header, opt) $INCFLAGS << " " << opt found = true break end end found end end end
Weist mkmf an, nach dem gegebenen header in einem der bereitgestellten paths zu suchen, und gibt zurück, ob er in diesen Pfaden gefunden wurde.
Wenn die Header-Datei gefunden wird, wird der Pfad, auf dem sie gefunden wurde, zur Liste der Verzeichnisse hinzugefügt, die an den Compiler gesendet werden (über den -I-Switch).
Source
# File lib/mkmf.rb, line 1164 def find_library(lib, func, *paths, &b) dir_config(lib) lib = with_config(lib+'lib', lib) paths = paths.flat_map {|path| path.split(File::PATH_SEPARATOR)} checking_for checking_message(func && func.funcall_style, LIBARG%lib) do libpath = $LIBPATH libs = append_library($libs, lib) begin until r = try_func(func, libs, &b) or paths.empty? $LIBPATH = libpath | [paths.shift] end if r $libs = libs libpath = nil end ensure $LIBPATH = libpath if libpath end r end end
Gibt zurück, ob der Einstiegspunkt func in der Bibliothek lib in einem der angegebenen paths gefunden werden kann, wobei paths ein Array von Strings ist. Wenn func nil ist, wird die Funktion main() als Einstiegspunkt verwendet.
Wenn lib gefunden wird, wird der Pfad, auf dem es gefunden wurde, zur Liste der durchsuchten und verknüpften Bibliotheks-Pfade hinzugefügt.
Source
# File lib/mkmf.rb, line 1261 def have_framework(fw, &b) if Array === fw fw, header = *fw else header = "#{fw}.h" end checking_for fw do src = cpp_include("#{fw}/#{header}") << "\n" "int main(void){return 0;}" opt = " -framework #{fw}" if try_link(src, opt, &b) or (objc = try_link(src, "-ObjC#{opt}", &b)) $defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp)) # TODO: non-worse way than this hack, to get rid of separating # option and its argument. $LDFLAGS << " -ObjC" if objc and /(\A|\s)-ObjC(\s|\z)/ !~ $LDFLAGS $LIBS << opt true else false end end end
Gibt zurück, ob das gegebene framework auf Ihrem System gefunden werden kann. Wenn gefunden, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der Framework-Name in Großbuchstaben verwendet wird, dem HAVE_FRAMEWORK_ vorangestellt ist.
Wenn beispielsweise have_framework('Ruby') true zurückgibt, wird das Präprozessormakro HAVE_FRAMEWORK_RUBY an den Compiler übergeben.
Wenn fw ein Paar aus dem Framework-Namen und dessen Header-Dateinamen ist, wird diese Header-Datei geprüft, anstatt der normalerweise verwendeten Header-Datei, die denselben Namen wie das Framework hat.
Source
# File lib/mkmf.rb, line 1198 def have_func(func, headers = nil, opt = "", &b) checking_for checking_message(func.funcall_style, headers, opt) do if try_func(func, $libs, headers, opt, &b) $defs << "-DHAVE_#{func.sans_arguments.tr_cpp}" true else false end end end
Gibt zurück, ob die Funktion func in den gemeinsamen Header-Dateien oder in den von Ihnen bereitgestellten headers gefunden werden kann. Wenn gefunden, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der Funktionsname in Großbuchstaben verwendet wird, dem HAVE_ vorangestellt ist.
Um Funktionen in einer zusätzlichen Bibliothek zu prüfen, müssen Sie diese Bibliothek zuerst mit have_library() prüfen. func soll entweder ein reiner Funktionsname oder ein Funktionsname mit Argumenten sein.
Wenn beispielsweise have_func('foo') true zurückgibt, wird das Präprozessormakro HAVE_FOO an den Compiler übergeben.
Source
# File lib/mkmf.rb, line 1238 def have_header(header, preheaders = nil, opt = "", &b) dir_config(header[/.*?(?=\/)|.*?(?=\.)/]) checking_for header do if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b) $defs.push(format("-DHAVE_%s", header.tr_cpp)) true else false end end end
Gibt zurück, ob die gegebene header-Datei auf Ihrem System gefunden werden kann. Wenn gefunden, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der Header-Dateiname in Großbuchstaben verwendet wird, dem HAVE_ vorangestellt ist.
Wenn beispielsweise have_header('foo.h') true zurückgibt, wird das Präprozessormakro HAVE_FOO_H an den Compiler übergeben.
Source
# File lib/mkmf.rb, line 1138 def have_library(lib, func = nil, headers = nil, opt = "", &b) dir_config(lib) lib = with_config(lib+'lib', lib) checking_for checking_message(func && func.funcall_style, LIBARG%lib, opt) do if COMMON_LIBS.include?(lib) true else libs = append_library($libs, lib) if try_func(func, libs, headers, opt, &b) $libs = libs true else false end end end end
Gibt zurück, ob der gegebene Einstiegspunkt func in lib gefunden werden kann. Wenn func nil ist, wird standardmäßig der Einstiegspunkt main() verwendet. Wenn gefunden, wird die Bibliothek zur Liste der zu verwendenden Bibliotheken beim Verknüpfen Ihrer Erweiterung hinzugefügt.
Wenn headers angegeben sind, werden diese Header-Dateien als Header-Dateien einbezogen, in denen nach func gesucht wird.
Der tatsächliche Name der zu verknüpfenden Bibliothek kann durch die Konfigurationsoption --with-FOOlib geändert werden.
Source
# File lib/mkmf.rb, line 1121 def have_macro(macro, headers = nil, opt = "", &b) checking_for checking_message(macro, headers, opt) do macro_defined?(macro, cpp_include(headers), opt, &b) end end
Gibt zurück, ob macro entweder in den gemeinsamen Header-Dateien oder in den von Ihnen bereitgestellten headers definiert ist.
Alle Optionen, die Sie an opt übergeben, werden an den Compiler weitergegeben.
Source
# File lib/mkmf.rb, line 1326 def have_struct_member(type, member, headers = nil, opt = "", &b) checking_for checking_message("#{type}.#{member}", headers) do if try_compile(<<"SRC", opt, &b) #{cpp_include(headers)} /*top*/ int s = (char *)&((#{type}*)0)->#{member} - (char *)0; #{MAIN_DOES_NOTHING} SRC $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp)) $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility true else false end end end
Gibt zurück, ob die Struktur vom Typ type das member enthält. Wenn nicht oder der Strukturtyp nicht gefunden werden kann, wird false zurückgegeben. Sie können optional zusätzliche headers angeben, in denen nach der Struktur gesucht werden soll (zusätzlich zu den gemeinsamen Header-Dateien).
Wenn gefunden, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der Typname und der Membername in Großbuchstaben verwendet werden, dem HAVE_ vorangestellt ist.
Wenn beispielsweise have_struct_member('struct foo', 'bar') true zurückgibt, wird das Präprozessormakro HAVE_STRUCT_FOO_BAR an den Compiler übergeben.
HAVE_ST_BAR wird ebenfalls zur Abwärtskompatibilität definiert.
Source
# File lib/mkmf.rb, line 1220 def have_var(var, headers = nil, opt = "", &b) checking_for checking_message(var, headers, opt) do if try_var(var, headers, opt, &b) $defs.push(format("-DHAVE_%s", var.tr_cpp)) true else false end end end
Gibt zurück, ob die Variable var in den gemeinsamen Header-Dateien oder in den von Ihnen bereitgestellten headers gefunden werden kann. Wenn gefunden, wird ein Makro als Präprozessorkonstante an den Compiler übergeben, wobei der Variablenname in Großbuchstaben verwendet wird, dem HAVE_ vorangestellt ist.
Um Variablen in einer zusätzlichen Bibliothek zu prüfen, müssen Sie diese Bibliothek zuerst mit have_library() prüfen.
Wenn beispielsweise have_var('foo') true zurückgibt, wird das Präprozessormakro HAVE_FOO an den Compiler übergeben.
Source
# File lib/mkmf.rb, line 472 def log_src(src, heading="checked program was") src = src.split(/^/) fmt = "%#{src.size.to_s.size}d: %s" Logging::message <<"EOM" #{heading}: /* begin */ EOM src.each_with_index {|line, no| Logging::message fmt, no+1, line} Logging::message <<"EOM" /* end */ EOM end
Protokolliert src
Source
# File lib/mkmf.rb, line 285 def modified?(target, times) (t = File.mtime(target)) rescue return nil Array === times or times = [times] t if times.all? {|n| n <= t} end
Gibt den Zeitstempel der Datei target zurück, wenn sie existiert und neuer oder gleich wie alle times ist.
Source
# File lib/mkmf.rb, line 1952 def pkg_config(pkg, *options) fmt = "not found" def fmt.%(x) x ? x.inspect : self end checking_for "pkg-config for #{pkg}", fmt do _, ldir = dir_config(pkg) if ldir pkg_config_path = "#{ldir}/pkgconfig" if File.directory?(pkg_config_path) Logging.message("PKG_CONFIG_PATH = %s\n", pkg_config_path) envs = ["PKG_CONFIG_PATH"=>[pkg_config_path, ENV["PKG_CONFIG_PATH"]].compact.join(File::PATH_SEPARATOR)] end end if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig) # if and only if package specific config command is given elsif ($PKGCONFIG ||= (pkgconfig = with_config("pkg-config") {config_string("PKG_CONFIG") || ENV["PKG_CONFIG"] || "pkg-config"}) && find_executable0(pkgconfig) && pkgconfig) and xsystem([*envs, $PKGCONFIG, "--exists", pkg]) # default to pkg-config command pkgconfig = $PKGCONFIG args = [pkg] elsif find_executable0(pkgconfig = "#{pkg}-config") # default to package specific config command, as a last resort. else pkgconfig = nil end if pkgconfig get = proc {|opts| opts = Array(opts).map { |o| "--#{o}" } opts = xpopen([*envs, pkgconfig, *opts, *args], err:[:child, :out], &:read) Logging.open {puts opts.each_line.map{|s|"=> #{s.inspect}"}} if $?.success? opts = opts.strip libarg, libpath = LIBARG, LIBPATHFLAG.strip opts = opts.shellsplit.map { |s| if s.start_with?('-l') libarg % s[2..] elsif s.start_with?('-L') libpath % s[2..] else s end }.quote.join(" ") opts end } end orig_ldflags = $LDFLAGS if get and !options.empty? get[options] elsif get and try_ldflags(ldflags = get['libs']) if incflags = get['cflags-only-I'] $INCFLAGS << " " << incflags cflags = get['cflags-only-other'] else cflags = get['cflags'] end libs = get['libs-only-l'] if cflags $CFLAGS += " " << cflags $CXXFLAGS += " " << cflags end if libs ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") else libs, ldflags = Shellwords.shellwords(ldflags).partition {|s| s =~ /-l([^ ]+)/ }.map {|l|l.quote.join(" ")} end $libs += " " << libs $LDFLAGS = [orig_ldflags, ldflags].join(' ') Logging::message "package configuration for %s\n", pkg Logging::message "incflags: %s\ncflags: %s\nldflags: %s\nlibs: %s\n\n", incflags, cflags, ldflags, libs [[incflags, cflags].join(' '), ldflags, libs] else Logging::message "package configuration for %s is not found\n", pkg nil end end end
Gibt Kompilier-/Verknüpfungsinformationen über eine installierte Bibliothek in einem Tupel von [cflags, ldflags, libs] zurück, indem der Befehl verwendet wird, der zuerst in den folgenden Befehlen gefunden wird
-
Wenn
--with-{pkg}-config={command}über die Befehlszeilenoption gegeben ist:{command} {options} -
{pkg}-config {options} -
pkg-config {options} {pkg}
Wobei options der Optionsname ohne Bindestriche ist, z. B. "cflags" für das Flag --cflags.
Die erhaltenen Werte werden an $INCFLAGS, $CFLAGS, $LDFLAGS und $libs angehängt.
Wenn ein oder mehrere options-Argumente gegeben sind, wird der Konfigurationsbefehl mit den Optionen aufgerufen und eine bereinigte Ausgabezeichenkette zurückgegeben, ohne die oben genannten globalen Werte zu ändern.
Source
# File lib/mkmf.rb, line 1624 def what_type?(type, member = nil, headers = nil, &b) m = "#{type}" var = val = "*rbcv_var_" func = "rbcv_func_(void)" if member m << "." << member else type, member = type.split('.', 2) end if member val = "(#{var}).#{member}" end prelude = [cpp_include(headers).split(/^/)] prelude << ["typedef #{type} rbcv_typedef_;\n", "extern rbcv_typedef_ *#{func};\n", "rbcv_typedef_ #{var};\n", ] type = "rbcv_typedef_" fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s" if typeof var = "*rbcv_member_" func = "rbcv_mem_func_(void)" member = nil type = "rbcv_mem_typedef_" prelude[-1] << "typedef #{typeof}(#{val}) #{type};\n" prelude[-1] << "extern #{type} *#{func};\n" prelude[-1] << "#{type} #{var};\n" val = var end def fmt.%(x) x ? super : "unknown" end checking_for checking_message(m, headers), fmt do if scalar_ptr_type?(type, member, prelude, &b) if try_static_assert("sizeof(*#{var}) == 1", prelude) return "string" end ptr = "*" elsif scalar_type?(type, member, prelude, &b) unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude) unsigned = "unsigned" end ptr = "" else next end type = UNIVERSAL_INTS.find do |t| pre = prelude unless member pre += [["#{unsigned} #{t} #{ptr}#{var};\n", "extern #{unsigned} #{t} #{ptr}*#{func};\n"]] end try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre) end type or next [unsigned, type, ptr].join(" ").strip end end
Gibt einen String zurück, der den Typ von type darstellt, oder member von type, wenn member nicht nil ist.
Source
# File lib/mkmf.rb, line 1767 def with_config(config, default=nil) config = config.sub(/^--with[-_]/, '') val = arg_config("--with-"+config) do if arg_config("--without-"+config) false elsif block_given? yield(config, default) else break default end end case val when "yes" true when "no" false else val end end
Testet auf die Anwesenheit einer --with-config oder --without-config Option. Gibt true zurück, wenn die With-Option gegeben ist, false, wenn die Without-Option gegeben ist, und andernfalls den Standardwert.
Dies kann nützlich sein, um benutzerdefinierte Definitionen wie Debug-Informationen hinzuzufügen.
Beispiel
if with_config("debug") $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG" end
Source
# File lib/mkmf.rb, line 695 def with_cppflags(flags) cppflags = $CPPFLAGS $CPPFLAGS = flags.dup ret = yield ensure $CPPFLAGS = cppflags unless ret end
Setzt $CPPFLAGS auf flags und gibt zurück. Wenn der Block einen falsy-Wert zurückgibt, wird $CPPFLAGS auf seinen vorherigen Wert zurückgesetzt, andernfalls bleibt er auf flags gesetzt.
flags-
ein C-Präprozessor-Flag als
String
Source
# File lib/mkmf.rb, line 457 def xpopen command, *mode, &block env, commands = expand_command(command) command = [env_quote(env), command].join(' ') Logging::open do case mode[0] when nil, Hash, /^r/ puts "#{command} |" else puts "| #{command}" end IO.popen(env, commands, *mode, &block) end end
Führt command ähnlich wie xsystem aus, gibt aber eine geöffnete Pipe weiter.
Source
# File lib/mkmf.rb, line 438 def xsystem(command, werror: false) env, command = expand_command(command) Logging::open do puts [env_quote(env), command.quote].join(' ') if werror result = nil Logging.postpone do |log| output = IO.popen(env, command, &:read) result = ($?.success? and File.zero?(log.path)) output end result else system(env, *command) end end end
Führt command mit variablenexpansion aus und gibt den Exit-Status wie bei Kernel#system zurück. Wenn werror true ist und die Fehlerausgabe nicht leer ist, wird false zurückgegeben. Die Ausgabe wird protokolliert.
Private Instanzmethoden
Source
# File lib/mkmf.rb, line 270 def rm_f(*files) opt = (Hash === files.last ? [files.pop] : []) FileUtils.rm_f(Dir[*files.flatten], *opt) end
Entfernt die Dateien.
Source
# File lib/mkmf.rb, line 277 def rm_rf(*files) opt = (Hash === files.last ? [files.pop] : []) FileUtils.rm_rf(Dir[*files.flatten], *opt) end
Entfernt die Dateien rekursiv.