Showing posts with label qrcodes. Show all posts
Showing posts with label qrcodes. Show all posts

Monday, 27 June 2011

qrcode generator with perl

There are some good pages for genereating QRcode and a lot of not so good ones. There are probably to many to decide which one to use so I decided to create yet another one:
pmg-qrcode




I have used
HTML::QRCode
Imager::QRCode



[...]
use Imager::QRCode;
use HTML::QRCode;

[...]

sub get_html_qr {
  my $text = shift;
  my $qrcode = HTML::QRCode->new->plot($text);
  return $qrcode;
}

sub print_qrimage {
  my $text = shift;
  my $imga_type = shift || 'png';
  my $qr = Imager::QRCode->new(
      size  =>  5,
      level => 'M',
    );

  $qr->plot($text)->write( fh => \*STDOUT, type => $img_type);
}


This is very simple, but .....
the difficult part is to have them working because the prerequisites not very well explained.

If you read the README for HTML::QRCode it says that it works out of the box with an standard cpan install. Well that is true if you have already Text::QRCode, that usually is not the case. Don't panic, lets install T::QRC and all will be fine. Humm... Marvin still depressed. Despite T::QRC also telling you about doing a standard install and all will go OK, again, that will only be true if you have all prerequisites already installed and in the default place. T::QRC needs libqrencode headers and libs and look for them at the root installed paths. The README does not say anything about this but the description of T::QRC gives a hint
DESCRIPTION ^
This module allows you to generate QR Code using ' ' and '*'. 
This module use libqrencode '2.0.0' and above.  

To make the long story short, I tried to install HTML::QRCode in my local-lib environment and failed because Text::QRCode missing. I tried to install T::QRC and failed because no lib-qrencode. Installed locally lib-qrencode and not able to install T::QRC because not knowing how to pass a 'prefix' option to Makefile.pl for the ld_lib and includes. Solved editing the Makefile.PL manually, adding an env-var for LD_RUN_PATH and install manually T::QRC and then cpan install of HTML::QRCode.

Long story:

HTML::QRCode needs Text::QRCode and Text::QRCode needs lib-qrencode:

HTML::QRCode:
t/00-load.t .. 1/1
        #   Failed test 'use Text::QRCode;'
        #   at t/00-load.t line 6.
        #     Tried to use 'Text::QRCode'.
        #     Error:  Can't load '/homes/pmg/.cpan/build/Text-QRCode-0.01-n4g2CG/blib/arch/auto/Text/QRCode/QRCode.so' for module Text::QRCode: libqrencode.so.3: cannot open shared object \
file: No such file or directory at /homes/pmg/pmg-soft/local-perl/lib/5.12.1/x86_64-linux/DynaLoader.pm line 200

I searched for libqrencode and download it:

# download
wget http://fukuchi.org/works/qrencode/qrencode-3.1.1.tar.gz
# extract
# install
[~/pmg-soft/src/qrencode-3.1.1]
$  ./configure --prefix=$HOME/pmg-soft
$ make
$ make install

And obtained a helpful message that I save for later:

----------------------------------------------------------------------
Libraries have been installed in:
/homes/pmg/pmg-soft/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Now I have a T::QRC build extracted somewhere (I can see the path in the error message) [ Error: Can't load '/homes/pmg/.cpan/build/Text-QRCode-0.01-n4g2CG/blib/arch/auto/Text/QRCode/QRCode.so'].

I went there and read the Makefile.PL. It has two places (includes and ld-lib) where I need to add the path for my local lib-qrencode files:

a) the directives for the Makefile

sub MY::post_constants {
  [...]
  return <<"POST_CONST";
  CCFLAGS += $define -I/homes/pmg/pmg-soft/include
  LDDLFLAGS += -L/homes/pmg/pmg-soft/lib -lqrencode
  LDFLAGS += -L/homes/pmg/pmg-soft/lib -lqrencode
  POST_CONST
}
b) the comand for testing that the lib-qrencode exist (testing existence by compilation success)
sub test_libqrencode {
  my $compile_cmd
        = 'cc -I/homes/pmg/pmg-soft/include -I/usr/local/include -I/usr/include -L/homes/pmg/pmg-soft/lib -L/usr/lib -L/usr/local/lib -lqrencode';
  [..]
}
Then exported the environmental variable 'LD_RUN_PATH':
export LD_RUN_PATH=/homes/pmg/pmg-soft/lib
$ make clean
$ perl Makefile.PL 
| Cannot determine perl version info from lib/Text/QRCode.pm
| Checking if your kit is complete...
| Looks good 
| Writing Makefile for Text::QRCode
$ make          
$ make test
| PERL_DL_NONLAZY=1 /homes/pmg/pmg-soft//local-perl/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'blib/lib', 'blib/arch')" t/00-load.t t/01-plot.t
| t/00-load.t .. 1/1 # Testing Text::QRCode 0.01, Perl 5.012001, /homes/pmg/pmg-soft//local-perl/bin/perl
| t/00-load.t .. ok
| t/01-plot.t .. ok
| All tests successful.
| Files=2, Tests=3,  0 wallclock secs ( 0.02 usr  0.03 sys +  0.06 cusr  0.04 csys =  0.15 CPU)
| Result: PASS
$ make install
|Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
|Installing /homes/pmg/pmg-soft/local-perl/local-lib/lib/perl5/x86_64-linux/auto/Text/QRCode/QRCode.so
|Installing /homes/pmg/pmg-soft/local-perl/local-lib/lib/perl5/x86_64-linux/auto/Text/QRCode/QRCode.bs  
|Installing /homes/pmg/pmg-soft/local-perl/local-lib/lib/perl5/x86_64-linux/Text/QRCode.pm
|Installing /homes/pmg/pmg-soft/local-perl/local-lib/man/man3/Text::QRCode.3
|Appending installation info to /homes/pmg/pmg-soft/local-perl/local-lib/lib/perl5/x86_64-linux/perllocal.pod

Then go to cpan and intall HTML::QRCode
cpan[2]> install HTML::QRCode 

That's all, happy hacking.


Pablo