Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Win32/MingW SetupAPI usage woes with Inline::C

by tlhackque (Beadle)
on Apr 23, 2018 at 01:08 UTC ( [id://1213396]=perlquestion: print w/replies, xml ) Need Help??

tlhackque has asked for the wisdom of the Perl Monks concerning the following question:

I'm probably missing something simple, but could use some help.

Attempts to use libSetupAPI under Windows 10 using Inline::C with MingW fail to link. ActivePerl 5.22.1 MSWin32-x64-multi-thread, ActiveState 2201

The problem is that the SetupAPI symbols fail to resolve. I have updated MinGW & Inline::C to today's latest versions. Here is a simple reproducer: (I know it doesn't do anything - it's cut down to the link issue.)

file: inline.pl #!/usr/bin/perl use 5.10.0; use warnings; use strict; use Inline( C => Config => libs => '-LC:\\MinGW\\lib -lSetupAPI', print_info => 1, BUILD_NOISY => 1, ); use Inline C => << 'EOC'; #include <windows.h> #include <stdio.h> #include <initguid.h> #include <devguid.h> #include <regstr.h> #include <setupapi.h> char *wrap_SetupDiGetClassDevs( ) { HDEVINFO hDevInfo; // Create a HDEVINFO with all present CDROM devices. hDevInfo = SetupDiGetClassDevs( &GUID_DEVCLASS_CDROM, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERF +ACE ); if (hDevInfo == INVALID_HANDLE_VALUE) croak("INVALID_HANDLE_VALUE returned"); return (char *)hDevInfo; } EOC
Here is an attempt to load the code. Note that libsetupapi.a is included in the linker (g++) command after inline_pl_(hex).o. The undefined reference is for SetupDiGetClassDevs. The file exists, and strings show the symbol, though with the @size decoration. I must be missing some required name mapping.
Synopsis(the output is quite cluttered): C:\PERL-5~1.1-6\site\bin\g++.exe inline_pl_7744.def \ -o blib\arch\auto\inline_pl_7744\inline_pl_7744.dll \ -mdll -s -static-libgcc -static-libstdc++ \ -L"C:\Perl-5.22.1-64\lib\CORE" \ -L"C:\MinGW\x86_64-w64-mingw32\lib" \ inline_pl_7744.o \ "C:\Perl-5.22.1-64\lib\CORE\libperl522.a" \ "C:\MinGW\lib\libSetupAPI.a" [snip...] inline_pl_7744.o:inline_pl_7744.c:(.text+0x18): undefined reference to + `__imp_SetupDiGetClassDevsA' Here is the full output (less the post-error traceback) perl -d inline.pl Loading DB routines from perl5db.pl version 1.49 Editor support available. Enter h or 'h h' for help, or 'perldoc perldebug' for more help. validate Stage <-----------------------Information Section--------------------------- +--------> Information about the processing of your Inline C code: Your source code needs to be compiled. I'll use this build directory: C:\Users\timothe\Software\Development\cdindex\_Inline\build\inline_pl_ +7744 and I'll install the executable as: C:\Users\timothe\Software\Development\cdindex\_Inline\lib\auto\inline_ +pl_7744\inline_pl_7744.dll get_maps Stage The following Inline C function(s) have been successfully bound to Per +l: char * wrap_SetupDiGetClassDevs() <-----------------------End of Information Section-------------------- +--------> Starting Build Preprocess Stage Finished Build Preprocess Stage Starting Build Parse Stage Finished Build Parse Stage Starting Build Glue 1 Stage Finished Build Glue 1 Stage Starting Build Glue 2 Stage Finished Build Glue 2 Stage Starting Build Glue 3 Stage Finished Build Glue 3 Stage Starting Build Compile Stage Starting "perl Makefile.PL" Stage Generating a dmake-style Makefile Writing Makefile for inline_pl_7744 Writing MYMETA.yml and MYMETA.json Finished "perl Makefile.PL" Stage Starting "make" Stage Running Mkbootstrap for inline_pl_7744 () "C:\Perl-5.22.1-64\bin\perl.exe" -MExtUtils::Command -e chmod -- 644 " +inline_pl_7744.bs" "C:\Perl-5.22.1-64\bin\perl.exe" -MExtUtils::Command::MM -e cp_nonempt +y -- inline_pl_7744.bs blib\arch\auto\inline_pl_7744\inline_pl_7744.b +s 644 "C:\Perl-5.22.1-64\bin\perl.exe" "C:\Perl-5.22.1-64\lib\ExtUtils\xsubp +p" -typemap "C:\Perl-5.22.1-64\lib\ExtUtils\typemap" inline_pl_7744 +.xs > inline_pl_7744.xsc "C:\Perl-5.22.1-64\bin\perl.exe" -MExtUtils::Command -e mv -- inline_p +l_7744.xsc inline_pl_7744.c C:\PERL-5~1.1-6\site\bin\gcc.exe -c -I"C:/Users/timothe/Software/Deve +lopment/cdindex" -s -O2 -DWIN32 -DWIN64 -DCONSERVATIVE -DPERL_TEXTMO +DE_SCRIPTS -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICI +T_SYS -fwrapv -fno-strict-aliasing -mms-bitfields -s -O2 -DV +ERSION=\"0.00\" -DXS_VERSION=\"0.00\" "-IC:\Perl-5.22.1-64\lib\CO +RE" inline_pl_7744.c "C:\Perl-5.22.1-64\bin\perl.exe" -MExtUtils::Mksymlists \ -e "Mksymlists('NAME'=>\"inline_pl_7744\", 'DLBASE' => 'inline_pl +_7744', 'DL_FUNCS' => { }, 'FUNCLIST' => [], 'IMPORTS' => { }, 'DL_ +VARS' => []);" C:\PERL-5~1.1-6\site\bin\g++.exe inline_pl_7744.def -o blib\arch\auto\ +inline_pl_7744\inline_pl_7744.dll -mdll -s -static-libgcc -static-lib +stdc++ -L"C:\Perl-5.22.1-64\lib\CORE" -L"C:\MinGW\x86_64-w64-mingw32\ +lib" inline_pl_7744.o "C:\Perl-5.22.1-64\lib\CORE\libperl522.a" "C: +\MinGW\lib\libSetupAPI.a" "C:\MinGW\lib\libmoldname.a" "C:\MinGW\lib\ +libkernel32.a" "C:\MinGW\lib\libuser32.a" "C:\MinGW\lib\libgdi32.a" " +C:\MinGW\lib\libwinspool.a" "C:\MinGW\lib\libcomdlg32.a" "C:\MinGW\li +b\libadvapi32.a" "C:\MinGW\lib\libshell32.a" "C:\MinGW\lib\libole32.a +" "C:\MinGW\lib\liboleaut32.a" "C:\MinGW\lib\libnetapi32.a" "C:\MinGW +\lib\libuuid.a" "C:\MinGW\lib\libws2_32.a" "C:\MinGW\lib\libmpr.a" "C +:\MinGW\lib\libwinmm.a" "C:\MinGW\lib\libversion.a" "C:\MinGW\lib\lib +odbc32.a" "C:\MinGW\lib\libodbccp32.a" "C:\MinGW\lib\libcomctl32.a" - +Wl,--enable-auto-image-base inline_pl_7744.o:inline_pl_7744.c:(.text+0x18): undefined reference to + `__imp_SetupDiGetClassDevsA' collect2: ld returned 1 exit status dmake.exe: Error code 129, while making 'blib\arch\auto\inline_pl_774 +4\inline_pl_7744.dll' [snip] dir "C:\MinGW\lib\libSetupAPI.a" Volume in drive C is Boot Disk Volume Serial Number is E315-E929 Directory of C:\MinGW\lib 06-Dec-17 15:10 319,374 libsetupapi.a

Thanks in advance for any clues.

This communication may not represent my employer's views, if any, on the matters discussed.

Replies are listed 'Best First'.
Re: Win32/MingW SetupAPI usage woes with Inline::C
by syphilis (Archbishop) on Apr 23, 2018 at 04:03 UTC
    undefined reference to `__imp_SetupDiGetClassDevsA'


    I think the problem is the line:
    libs => '-LC:\\MinGW\\lib -lSetupAPI',
    I think it might be finding the wrong libsetupapi.a.
    Try replacing that line with:
    libs => '-lsetupapi',
    The correct 'libsetupapi.a' is in a location that should be found by default - so there should be no need to specify a location for it.
    At least, for me, when I made that change to your script, it built just fine. Prior to that I was getting the same error as you.

    Cheers,
    Rob

      Thanks. Sorry I didn't see this sooner.

      I tried that first. So, after reading your note I searched the entire C: drive (where MinGW is installed).

      I found another libsetupapi.a in C:\Perl-5.22.1-64\site\lib\auto\MinGW\x86_64-w64-mingw32\lib

      And specifying that does compile. Apparently Inline::C installs it there. But hardcoding a path makes this very unportable to another system.

      So, the new question is: how do I get that path portably?

      I can use Config; $Config{sitelibexp} for part of the way: 'C:\Perl-5.22.1-64\site\lib' (which also appears in @INC)

      But this is magic: "\auto\MinGW\x86_64-w64-mingw32\lib" There some pkg-config -like method for Perl...

      For now, I use this expensive hack

      use File::Find; my $libpath; my $incpath; BEGIN { find( { wanted => sub { /^libsetupapi\.a$/i && ($libpath ||= $File::Find::dir); /^setupapi\.h$/i && ($incpath ||= $File::Find::dir); }, follow => 1, follow_skip => 2 }, @INC ); die( "No MinGW libsetupapi $libpath $incpath\n" ) unless( $libpath && $incpath ); } use Inline( C => Config => libs => "-L$libpath -lSetupAPI", INC => "-I$incpath", );

      There must be a better way. Meantime, on to figuring out the mysteries of the Windoze APIs.

Re: Win32/MingW SetupAPI usage woes with Inline::C
by shmem (Chancellor) on Apr 23, 2018 at 02:10 UTC
    This communication may not represent my employer's views, if any, on the matters discussed.

    This communication represents my very own view, unless otherwise stated.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1213396]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-04-25 21:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found