# Hacking mkmf.rb

**URL:** <https://www.ruby-forum.com/t/hacking-mkmf-rb/90813>\
**Category:** Ruby\
**Created:** [April 2, 2007, 12:35am UTC](https://www.ruby-forum.com/t/hacking-mkmf-rb/90813 "2007-04-02T00:35:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tim-hunter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/278dde/32.png) [@tim-hunter](https://www.ruby-forum.com/u/tim-hunter)\
**Post date:** [April 2, 2007, 12:35am UTC](https://www.ruby-forum.com/t/hacking-mkmf-rb/90813/1 "2007-04-02T00:35:42Z")

</div>

I’m in the process of replacing RMagick’s configure/make/make install  
process with a pure-Ruby solution using just setup.rb or RubyGems and  
extconf.rb. I’ve been able to successfully replace configure.ac with  
extconf.rb except for two things. First, mkmf.rb does not have a method  
that tests for the presence of a specific value in an enum. Second,  
mkmf.rb wants to put all its feature symbols (-DHAVE\_SOMETHING) on the  
gcc command line but RMagick may have upwards of 100 such symbols and  
I’m afraid that that many will exceed some system’s limit on the maximum  
length of a command’s arguments. I’d rather put these symbols in a  
config.h file.

So i’ve added two methods to my extconf.rb. (I’ve added them below). Any  
comments on the risks I’m introducing to my extconf.rb and how I might  
mitigate them? I’ve tested my extconf.rb with Ruby 1.8.2, 1.8.3, 1.8.4,  
1.8.5, and 1.8.6. What about going forward? I would like to minimize the  
chances of my having to fix my extconf.rb when Ruby 1.8.7 comes out.

(I learned that my extconf.rb is not compatible with Ruby 1.8.0 or  
1.8.1, notably because have\_library has a different signature in those  
releases. That’s not a problem for me.)

# Test for a specific value in an enum type

def have\_enum\_value(enum, value, headers=nil, &b)  
checking\_for “#{enum}.#{value}” do  
if try\_compile(\<\<“SRC”, &b)  
#{COMMON\_HEADERS}  
#{cpp\_include(headers)}  
/_top_/  
int main(){ #{enum} x = #{value}; x = x; return 0; }  
SRC  
$defs.push(format("-DHAVE\_%s", value.upcase))  
true  
else  
false  
end  
end  
end

# Create a config.h file from the $defs array.

def create\_config\_file(file)  
message “creating #{file}\n”  
File.open(file, “w”) do |f|  
while (sym = $defs.shift)  
define = sym.sub(/\A-D/, ‘#define ‘)  
if define[’=’]  
define[’=’] = ’ ’ # symbols with values  
else  
define \<\< ’ 1’ # symbols without values  
end  
f.puts define  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![tim-hunter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/278dde/32.png) [@tim-hunter](https://www.ruby-forum.com/u/tim-hunter)\
**Post date:** [April 2, 2007, 4:45am UTC](https://www.ruby-forum.com/t/hacking-mkmf-rb/90813/2 "2007-04-02T04:45:56Z")

</div>

On Apr 1, 4:34 pm, Timothy H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m in the process of replacing RMagick’s configure/make/make install  
> process with a pure-Ruby solution using just setup.rb or RubyGems and  
> extconf.rb. I’ve been able to successfully replace configure.ac with  
> extconf.rb except for two things. First, mkmf.rb does not have a method  
> that tests for the presence of a specific value in an enum. Second,  
> mkmf.rb wants to put all its feature symbols (-DHAVE\_SOMETHING) on the  
> gcc command line but RMagick may have upwards of 100 such symbols and  
> I’m afraid that that many will exceed some system’s limit on the maximum  
> length of a command’s arguments. I’d rather put these symbols in a  
> config.h file.

I requested have\_enum\_member two years ago:

[http://rubyforge.org/tracker/index.php?func=detail&aid=1486&group\_id=426&atid=1700](http://rubyforge.org/tracker/index.php?func=detail&aid=1486&group_id=426&atid=1700).

That eventually turned into have\_const:

[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/4430](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/4430).

Note that “checking\_for type” should be “checking\_for const”. I think  
it just got lost in the shuffle. I’ll bring it up again on ruby-core.

> # Test for a specific value in an enum type
> 
> ```
> else
> define = sym.sub(/\A-D/, '#define ')
> if define['=']
> define['='] = ' ' # symbols with values
> else
> define << ' 1' # symbols without values
> end
> f.puts define
> end
> 
> ```
> 
> end  
> end

create\_config\_file looks reasonable to me.

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![tim-hunter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/278dde/32.png) [@tim-hunter](https://www.ruby-forum.com/u/tim-hunter)\
**Post date:** [April 9, 2007, 1:11am UTC](https://www.ruby-forum.com/t/hacking-mkmf-rb/90813/3 "2007-04-09T01:11:36Z")

</div>

Timothy H. wrote:

> Second, mkmf.rb wants to put all its feature symbols  
> (-DHAVE\_SOMETHING) on the gcc command line but RMagick may have  
> upwards of 100 such symbols and I’m afraid that that many will exceed  
> some system’s limit on the maximum length of a command’s arguments.  
> I’d rather put these symbols in a config.h file.  
> I’ve just found the create\_header method in mkmf.rb. This looks like it  
> does everything I need.
