Mkmf have_func usage

Hi,

I’m wondering if I’m using the have_func from lib mkmf correctly, as I
can’t seem to get a true out of it?

require "mkmf"

have_func( "iconv_open", 

“/Library/Frameworks/Libiconv.framework/Headers”)
checking for iconv_open() in
/Library/Frameworks/Libiconv.framework/Headers… no
=> false

have_func( "iconv_open", 

“/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h”)
checking for iconv_open() in
/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h…
no
=> false

but if I open up the iconv.h file from above I can quite clearly see
iconv_open is defined (even though I know not C)

#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif

Any push in the right direction will be much appreciated.

Iain

On Mar 24, 11:55pm, Iain B. [email protected] wrote:

have_func( “iconv_open”,
“/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h”)
checking for iconv_open() in
/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h… no
=> false

but if I open up the iconv.h file from above I can quite clearly see iconv_open
is defined (even though I know not C)

#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif

Any push in the right direction will be much appreciated.

My first suggestion would be check the mkmf.log file that was
generated and see if it offers up any clues.

Regards,

Dan

On 25 Mar 2011, at 06:43, Daniel B. wrote:

My first suggestion would be check the mkmf.log file that was
generated and see if it offers up any clues.

This is the mkmf.log generated, and I don’t really understand what I’m
looking at in there:

have_func: checking for iconv_open() in
/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h…
-------------------- no

"gcc -o conftest
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1/x86_64-darwin10.4.0
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1/ruby/backward
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1
-I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE=1 -fno-common
-pipe conftest.c -L.
-L/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib -L.
-L/usr/local/lib -lruby.1.9.1-static -lpthread -ldl -lobjc "
checked program was:
/* begin /
1: #include “ruby.h”
2:
3: int main() {return 0;}
/
end */

"gcc -o conftest
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1/x86_64-darwin10.4.0
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1/ruby/backward
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1
-I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE=1 -fno-common
-pipe conftest.c -L.
-L/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib -L.
-L/usr/local/lib -lruby.1.9.1-static -lpthread -ldl -lobjc "
Undefined symbols:
“_libiconv_open”, referenced from:
_t in ccZQeC6u.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
checked program was:
/* begin /
1: #include “ruby.h”
2:
3: #include
</Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h>
4:
5: /top/
6: int main() {return 0;}
7: int t() { void ((volatile p)()); p = (void (()()))iconv_open;
return 0; }
/
end */

"gcc -o conftest
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1/x86_64-darwin10.4.0
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1/ruby/backward
-I/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/include/ruby-1.9.1
-I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE=1 -fno-common
-pipe conftest.c -L.
-L/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib -L.
-L/usr/local/lib -lruby.1.9.1-static -lpthread -ldl -lobjc "
conftest.c: In function t:
conftest.c:7: error: too few arguments to function libiconv_open
checked program was:
/* begin /
1: #include “ruby.h”
2:
3: #include
</Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h>
4:
5: /top/
6: int main() {return 0;}
7: int t() { iconv_open(); return 0; }
/
end */

On 25 Mar 2011, at 18:44, Ryan D. wrote:

3: #include
</Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h>

4:
5: /top/
6: int main() {return 0;}
7: int t() { iconv_open(); return 0; }
/* end */

The error is here and is pretty clear whether it were C or ruby. It failed
because it wasn’t called with the right number of args.

It’s one thing to be able to read it, it’s another thing to understand,
which I why I said I didn’t really understand what I was looking at.
Since I don’t use C and this is the first time I’ve used the mkmf
library I was hoping for a hint at why this came out the way it did.

I was calling the arguments the way the nokogiri gem does in order to
try and fix a problem I’m having with it.

In the meantime I’ve found that using find_library brought back more
positive results.

Regards,
Iain

On Mar 25, 2011, at 14:11 , Iain B. wrote:

/* begin */

It’s one thing to be able to read it, it’s another thing to understand, which I
why I said I didn’t really understand what I was looking at. Since I don’t use C
and this is the first time I’ve used the mkmf library I was hoping for a hint at
why this came out the way it did.

My point is that f() when it should be f(arg1, …) is understandable in
any language.

I was calling the arguments the way the nokogiri gem does in order to try and
fix a problem I’m having with it.

In the meantime I’ve found that using find_library brought back more positive
results.

Yeah. Looking at nokogiri is a good idea:

asplode “libiconv” unless have_func(‘iconv_open’, ‘iconv.h’) or
have_library(‘iconv’, ‘iconv_open’, ‘iconv.h’)

which produces:

On 25 Mar 2011, at 22:11, Ryan D. wrote:

have_library: checking for iconv_open() in -liconv… -------------------- yes

Mine fails on this check, and I suspect it’s due to this set of
hard-coded paths:

HEADER_DIRS = [
    # First search /opt/local for macports
    '/opt/local/include',

    # Then search /usr/local for people that installed from source
    '/usr/local/include',

    # Check the ruby install locations
    INCLUDEDIR,

    # Finally fall back to /usr
    '/usr/include',
    '/usr/include/libxml2',
  ]

  LIB_DIRS = [
    # First search /opt/local for macports
    '/opt/local/lib',

    # Then search /usr/local for people that installed from source
    '/usr/local/lib',

    # Check the ruby install locations
    LIBDIR,

    # Finally fall back to /usr
    '/usr/lib',
  ]

  XML2_HEADER_DIRS = [
    '/opt/local/include/libxml2',
    '/usr/local/include/libxml2',
    File.join(INCLUDEDIR, "libxml2")
  ] + HEADER_DIRS
end

I’ve no idea why assumptions like this are made when variables like
PATH, C_INCLUDE_PATH, and
DYLD_LIBRARY_PATH/LD_LIBRARY_PATH/DYLD_FALLBACK_LIBRARY_PATH exist
exactly to avoid this and allow people to set up their systems to their
own liking?

Having said that, even if I pass these in it fails unless I use
find_library in place of have_library in the extconf.rb, and even then I
get more problems. I’ll keep hacking away. More comments in the code of
both the mkmf and nokogiri libs would’ve been nice too (since I’m having
a moan).

Regards,
Iain

On Mar 25, 2011, at 8:19, Iain B. [email protected] wrote:

7: int t() { iconv_open(); return 0; }
/* end */

The error is here and is pretty clear whether it were C or ruby. It
failed because it wasn’t called with the right number of args.

On Mar 27, 5:21pm, Albert S. [email protected] wrote:

That’s not a very good answer. have_func() is supposed to tell you if a
function exists; so it tries to link to that function. It can’t pass
args to the function because it doesn’t have any knowledge about the
function. The question is why “mkmf” fails to do this. I know that in C
you don’t have to specify correct (or any) arguments to a function (In
C++ it’s different).

Indeed, I tested this on my Linux box and it works fine with
“have_func(‘iconv_open’, ‘/usr/include/iconv.h’)”.

Based on the output of the mkmf.log file, I suspect a linkage issue.

Does it work if you try “have_library(‘iconv’)” or
“have_library(‘libiconv’)” first?

I’m also curious why those headers are under /Library/Frameworks, but
that’s another story I suppose.

Regards,

Dan

Ryan D. wrote in post #989277:

On Mar 25, 2011, at 8:19, Iain B. removed_email_addre[email protected] wrote:

7: int t() { iconv_open(); return 0; }
/* end */

The error is here and is pretty clear whether it were C or ruby. It
failed because it wasn’t called with the right number of args.

That’s not a very good answer. have_func() is supposed to tell you if a
function exists; so it tries to link to that function. It can’t pass
args to the function because it doesn’t have any knowledge about the
function. The question is why “mkmf” fails to do this. I know that in C
you don’t have to specify correct (or any) arguments to a function (In
C++ it’s different).

On 28 Mar 2011, at 22:51, Daniel B. wrote:

Indeed, I tested this on my Linux box and it works fine with
“have_func(‘iconv_open’, ‘/usr/include/iconv.h’)”.

Based on the output of the mkmf.log file, I suspect a linkage issue.

Does it work if you try “have_library(‘iconv’)” or
“have_library(‘libiconv’)” first?

from my irb:

require “mkmf”
=> true

have_library(‘iconv’)
checking for main() in -liconv… yes
=> true

have_func(‘iconv_open’,
‘/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/inconv.h’)
checking for iconv_open() in
/Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/inconv.h…
no
=> false

I’m also curious why those headers are under /Library/Frameworks, but
that’s another story I suppose.

Because that’s where user built libraries on a Mac are “supposed” to go
:slight_smile:

http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html

I stick all my stuff there, it’s much easier to use that /usr/local that
way.

Where it does fall down is when library writers assume that everyone
uses /usr/local. I struggle to think of a worse code smell right now
than hard-coded paths for nix systems, but maybe that’s just because
it’s affecting me. Taking a tip from the author(s) of nokogiri I
hardcoded the paths to my libs in extconf.rb and it started to build
fine, until another hard-coded path in another part of the code borked
everything. When I get some time I’ll track it down.

Regards,
Iain

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs