mkmf have_func usage

I

Iain Barnett

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?=20

require "mkmf"

have_func( "iconv_open", =
"/Library/Frameworks/Libiconv.framework/Headers")
checking for iconv_open() in =
/Library/Frameworks/Libiconv.framework/Headers... no
=3D> 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
=3D> 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=
 
D

Daniel Berger

Hi,

I'm wondering if I'm using the have_func from lib mkmf correctly, as I ca=
n't seem to get a `true` out of it?
=A0 =A0 require "mkmf"

=A0 =A0 have_func( "iconv_open", "/Library/Frameworks/Libiconv.framework/= Headers")
=A0 =A0 checking for iconv_open() in /Library/Frameworks/Libiconv.framewo= rk/Headers... no
=A0 =A0 =3D> false

=A0 =A0 have_func( "iconv_open", "/Library/Frameworks/Libiconv.framework/= Versions/1.13.1/include/iconv.h")
=A0 =A0 checking for iconv_open() in /Library/Frameworks/Libiconv.framewo=
rk/Versions/1.13.1/include/iconv.h... no
=A0 =A0 =3D> false

but if I open up the iconv.h file from above I can quite clearly see icon=
v_open is defined (even though I know not C)
=A0 =A0 #ifndef LIBICONV_PLUG
=A0 =A0 #define iconv_open libiconv_open
=A0 =A0 #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
 
I

Iain Barnett

=20
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=3D1 -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:=20
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=3D1 -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:=20
3: #include =
</Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h>
4:=20
5: /*top*/
6: int main() {return 0;}
7: int t() { void ((*volatile p)()); p =3D (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=3D1 -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 =91t=92:
conftest.c:7: error: too few arguments to function =91libiconv_open=92
checked program was:
/* begin */
1: #include "ruby.h"
2:=20
3: #include =
</Library/Frameworks/Libiconv.framework/Versions/1.13.1/include/iconv.h>
4:=20
5: /*top*/
6: int main() {return 0;}
7: int t() { iconv_open(); return 0; }
/* end */
 
R

Ryan Davis

conftest.c: In function =E2=80=98t=E2=80=99:
conftest.c:7: error: too few arguments to function =E2=80=98libiconv_open=E2= =80=99
checked program was:
/* begin */
1: #include "ruby.h"
2:=20
3: #include </Library/Frameworks/Libiconv.framework/Versions/1.13.1/includ= e/iconv.h>
4:=20
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 b=
ecause it wasn't called with the right number of args.=
 
I

Iain Barnett

=20
=20

=20
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=
 
R

Ryan Davis

=20
On 25 Mar 2011, at 18:44, Ryan Davis wrote:
=20
failed because it wasn't called with the right number of args.
=20
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.
=20
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:
have_func: checking for iconv_open() in iconv.h... = -------------------- no
=20
"gcc -o conftest -I. =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/=
universal-darwin10.0 -I. -I-I-I/opt/local/include =
-I-I-I/usr/local/include =
-I-I-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I-I-I/usr/include -I-I-I/usr/include/libxml2 =
-I/opt/local/include/libxml2 -I/usr/local/include/libxml2 =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include/libxm=
l2 -I-I/opt/local/include -I-I/usr/local/include =
-I-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I-I/usr/include -I-I/usr/include/libxml2 -I/opt/local/include =
-I/usr/local/include =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I/usr/include -I/usr/include/libxml2 -D_XOPEN_SOURCE =
-D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE =
-fno-common -pipe -fno-common -g -DXP_UNIX -O3 -Wall -Wcast-qual =
-Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -L. =
-L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib =
-L/opt/local/lib -L/usr/local/lib =
-L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib =
-L/usr/lib -L. -lruby -lpthread -ldl "
ld: warning: directory '/opt/local/lib' following -L not found
Undefined symbols:
"_iconv_open", referenced from:
_t in ccFFqxiP.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
checked program was:
/* begin */
1: #include <iconv.h>
2:=20
3: /*top*/
4: int main() { return 0; }
5: int t() { void ((*volatile p)()); p =3D (void ((*)()))iconv_open; = return 0; }
/* end */
=20
"gcc -o conftest -I. =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/=
universal-darwin10.0 -I. -I-I-I/opt/local/include =
-I-I-I/usr/local/include =
-I-I-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I-I-I/usr/include -I-I-I/usr/include/libxml2 =
-I/opt/local/include/libxml2 -I/usr/local/include/libxml2 =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include/libxm=
l2 -I-I/opt/local/include -I-I/usr/local/include =
-I-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I-I/usr/include -I-I/usr/include/libxml2 -I/opt/local/include =
-I/usr/local/include =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I/usr/include -I/usr/include/libxml2 -D_XOPEN_SOURCE =
-D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE =
-fno-common -pipe -fno-common -g -DXP_UNIX -O3 -Wall -Wcast-qual =
-Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -L. =
-L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib =
-L/opt/local/lib -L/usr/local/lib =
-L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib =
-L/usr/lib -L. -lruby -lpthread -ldl "
conftest.c: In function 't':
conftest.c:5: error: too few arguments to function 'iconv_open'
checked program was:
/* begin */
1: #include <iconv.h>
2:=20
3: /*top*/
4: int main() { return 0; }
5: int t() { iconv_open(); return 0; }
/* end */
=20
--------------------
=20
have_library: checking for iconv_open() in -liconv... = -------------------- yes
=20
"gcc -o conftest -I. =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/=
universal-darwin10.0 -I. -I-I-I/opt/local/include =
-I-I-I/usr/local/include =
-I-I-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I-I-I/usr/include -I-I-I/usr/include/libxml2 =
-I/opt/local/include/libxml2 -I/usr/local/include/libxml2 =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include/libxm=
l2 -I-I/opt/local/include -I-I/usr/local/include =
-I-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I-I/usr/include -I-I/usr/include/libxml2 -I/opt/local/include =
-I/usr/local/include =
-I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/include =
-I/usr/include -I/usr/include/libxml2 -D_XOPEN_SOURCE =
-D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE =
-fno-common -pipe -fno-common -g -DXP_UNIX -O3 -Wall -Wcast-qual =
-Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -L. =
-L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib =
-L/opt/local/lib -L/usr/local/lib =
-L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib =
-L/usr/lib -L. -lruby -liconv -lpthread -ldl "
 
I

Iain Barnett

-------------------- yes

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

HEADER_DIRS =3D [
# First search /opt/local for macports
'/opt/local/include',
=20
# Then search /usr/local for people that installed from source
'/usr/local/include',
=20
# Check the ruby install locations
INCLUDEDIR,
=20
# Finally fall back to /usr
'/usr/include',
'/usr/include/libxml2',
]
=20
LIB_DIRS =3D [
# First search /opt/local for macports
'/opt/local/lib',
=20
# Then search /usr/local for people that installed from source
'/usr/local/lib',
=20
# Check the ruby install locations
LIBDIR,
=20
# Finally fall back to /usr
'/usr/lib',
]
=20
XML2_HEADER_DIRS =3D [
'/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?=20

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=
 
A

Albert Schlef

Ryan Davis wrote in post #989277:
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).
 
D

Daniel Berger

Ryan Davis wrote in post #989277:



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
 
I

Iain Barnett

=20
Indeed, I tested this on my Linux box and it works fine with
"have_func('iconv_open', '/usr/include/iconv.h')".
=20
Based on the output of the mkmf.log file, I suspect a linkage issue.
=20
Does it work if you try "have_library('iconv')" or
"have_library('libiconv')" first?

from my irb:

require "mkmf"
=3D> true

have_library('iconv')
checking for main() in -liconv... yes
=3D> 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
=3D> false

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

Because that's where user built libraries on a Mac are "supposed" to go =
:)=20

=
http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BP=
Frameworks/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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top