1. Perl
  2. XS
  3. here

ExtUtils::MakeMaker - Customize Makefile.PL

ExtUtils::MakeMaker is used to explain how to write Makefile.PL . ..

Specify a test script

By default, the test scripts under the "t" directory are executed, but you may want to execute the test scripts in subdirectories in a deeper hierarchy.

In that case, use the test option. The following example allows the test script up to 3 levels down to be executed.

  test => {TESTS =>'t /*.t t /*/*.tt/*/*/*.t'}

Add files to be deleted when doing make clean, make real clean

Makefile.PL automatically creates a Makefile, which defines the commands that are executed by "make clean" and "make real clean".

Sometimes you may want to delete a particular file when you "make clean" or "make real clean".

In such a case, you can handle it by writing the following option in the WriteMakefile function in Makefile.PL.

clean => {FILES => "* .xyz foo"}
realclean => {FILES =>'$(INST_ARCHAUTODIR) /*.xyz'}

Please note that in FILES, it is necessary to describe the file name according to the make syntax rules.

How to rename the XS file

When you create an XS module using h2xs, if the namespace contains "::", the XS file name will be "last name.xs".

For example, if you create an XS module using h2xs with the name "Some::Module", the XS file name will be "Module.xs". This is a little unpleasant.

To give a free XS file name, you need to specify the XS file name in Makefile.PL.

For example, if you want to create an XS file with the name "SomeModule.xs", write as follows. Look only at the commented "XS Options" and "OBJECT" options. The other part is automatically generated.

use ExtUtils::MakeMaker;

WriteMakefile (
    NAME =>'Rstats::Element',
    VERSION_FROM =>'lib/Rstats/Element.pm',
    PREREQ_PM => {},
    ($] >= 5.005?
      (ABSTRACT_FROM =>'lib/Rstats/Element.pm',
       AUTHOR =>'A. U. Thor <kimoto@sakura.ne.jp>') :()),
    LIBS => [''],
    # XS option
    XS => {'SomeModule.xs' =>'SomeModule.c'},
    DEFINE =>'',
    INC =>'-I.',
    # OBJECT option
    OBJECT =>'SomeModule $(OBJ_EXT)'
);

Specify that "SomeModule.xs" should be named "SomeModule.c" in the XS option. This is an instruction to xsubpp to convert the XS file to a C source file.

However, this is not enough, and you also need to describe the C language file name to be compiled (this is described by the object name). Specify it with the OBJECT option. The "$(OBJ_EXT)" part is like a special make variable and is replaced with ".o".

If you write like this, "SomeModule.c" will be compiled. It's complicated.

Specify gcc optimization options

To specify gcc optimization options on XS Specify the OPTIMIZE option as a WriteMakefile option in Makefile.PL.

OPTIMIZE =>'-O3'

Specifying -O3 seems to give the strongest optimization.

The following is an example using the OPTIMIZE option.

use strict;
use warnings;
use ExtUtils::MakeMaker;

WriteMakefile (
    NAME =>'Rstats',
    AUTHOR =>'Yuki Kimoto <kimoto.yuki@gmail.com>',
    VERSION_FROM =>'lib/Rstats.pm',
    ABSTRACT_FROM =>'lib/Rstats.pm',
    ($ExtUtils::MakeMaker::VERSION >= 6.3002
      ? ('LICENSE'=>' perl')
      : ()),
    PL_FILES => {},
    PREREQ_PM => {
        'Test::More' => 0,
        'Object::Simple'=> '3.10',
        'Math::Round'=> '0.06',
        'Text::UnicodeTable::Simple'=> '0.09'
    },
    dist => {COMPRESS =>'gzip -9f', SUFFIX =>'gz',},
    clean => {FILES =>'Rstats-*'},
    CC =>'g ++',
    OPTIMIZE =>'-O3',
    LD =>'g ++',
    LIBS => [''],
    DEFINE =>'',
    INC =>'-I.',
    OBJECT =>'$(O_FILES)',
);

How to add a search path for a C/C ++ language header file in Makefile.PL

When writing Makefile.PL, you may want to change or add the location of C/C ++ header files. For ExtUtils::MakeMaker, you can set it with the INC and H options in the WriteMakefile.

The following settings assume that you have a C/C ++ header file in "Rstats_lib/include".

    INC =>'-I. -I./Rstats_lib/include',
    H => ['ppport.h', glob('Rstats_lib/include/*. h')],

Add header file include path

Use the option "INC" to add the include path for the header file. By default, the current directory is set, so "./Rstats_lib/include" is added to this.

    INC =>'-I. -I./Rstats_lib/include'

Do not delete the current directory settings. Because it is needed to read the header file "ppport.h".

This is an option passed to the compiler (such as gcc). Note that even if you specify multiple header file search paths, write the option "-I" multiple times instead of specifying it in the array reference.

Specify a list of header file names

The "H" option passes a list of header files. Specify all header files in the array reference. All header files under "Rstats_lib/include" are specified using "ppport.h" and the glob function.

    H => ['ppport.h', glob('Rstats_lib/include/*. h')],

If this is not specified, the dependency will not be resolved correctly when make is executed, so be sure to specify it. The "INC" option alone will compile successfully for the first time, but make will not understand the dependencies correctly.

How to add a search path for C/C ++ language source files in Makefile.PL

How can I store C/C ++ language source files in a different directory when writing an XS? You can do that if you write Makefile.PL well. Write the WriteMakefile options in Makefile.PL as follows:

    C => ['Rstats.c', glob('Rstats_lib/src/*. Cpp')],OBJECT =>'$(O_FILES)',
    DEFINE =>'-o $@'

This is the case when the module name is Rstats and the source file directory is "Rstats_lib/src". It is assumed that a file called Rstats.xs is located at the top "/". The source file type is a C ++ source file.

To make the image easier, I'll show you the structure of the directory and a complete example of Makefile.PL.

..
| - Changes
|-MANIFEST
|-MANIFEST.SKIP
| - Makefile.PL
|-README.md
| - Rstats.xs
| - Rstats_lib
| |-include
| | `- Rstats.h
| `- src
| | - Rstats_ElementFunc.cpp
| | - Rstats_Func.cpp
| | - Rstats_Main.cpp
| | - Rstats_Util.cpp
| | - Rstats_Vector.cpp
| `- Rstats_VectorFunc.cpp
| - lib
| | - Rstats
| | |-Class.pm
| | |-Func.pm
| | |-Object.pm
| | `- Util.pm
| `- Rstats.pm
|-ppport.h
`- t

The source code of Makefile.PL.

use 5.010001;

use strict;
use warnings;
use ExtUtils::MakeMaker;

use Config;

# C ++ compiler
my $cpp_compilers = {
  gcc =>'g ++',
  clang =>'clang ++',
  CC =>'CC'
};
my $cc = $cpp_compilers->{$Config{ccname}};
my $ld = $cc;

WriteMakefile (
    NAME =>'Rstats',
    AUTHOR =>'Yuki Kimoto <kimoto.yuki@gmail.com>',
    VERSION_FROM =>'lib/Rstats.pm',
    ABSTRACT_FROM =>'lib/Rstats.pm',
    ($ExtUtils::MakeMaker::VERSION >= 6.3002
      ? ('LICENSE'=>' perl')
      : ()),
    PL_FILES => {},
    META_MERGE => {
      requires => {perl => '5.010001'},
      resources => {
        license =>'http://www.opensource.org/licenses/artistic-license-2.0',
        bugtracker =>'https://github.com/yuki-kimoto/Rstats/issues',
        repository =>'https://github.com/yuki-kimoto/Rstats.git'
      }
    },
    PREREQ_PM => {
        'Object::Simple'=> '3.10',
        'Math::Round'=> '0.06',
        'Text::UnicodeTable::Simple'=> '0.09'
    },
    dist => {COMPRESS =>'gzip -9f', SUFFIX =>'gz',},
    clean => {FILES =>'Rstats-*'},
    CC => $cc,
    OPTIMIZE =>'-O3',
    LD => $ld,
    LIBS => [],
    DEFINE =>'',
    INC =>'-I. -I./Rstats_lib/include',
    C => ['Rstats.c', glob('Rstats_lib/src/*. Cpp')],
    OBJECT =>'$(O_FILES)',
    DEFINE =>'-o $@'
);

C language source file description

I think it is difficult to understand as it is, so I will explain the options of WriteMakefile.

    C => ['Rstats.c', glob('Rstats_lib/src/*. Cpp')],
    OBJECT =>'$(O_FILES)',
    DEFINE =>'-o $@'

First, write all the source code required for compilation with the option "C". "Rstats.c" corresponds to "Rstats.xs". I am using the glog function to get the cpp file under "Rstats_lib/src". If it was C language, the options in this part would be as follows.

    C => ['Rstats.c', glob('Rstats_lib/src/*. C')],

Internally, the file specified by the "C" option is stored in a variable called "C_FILES" in Makefile. In addition, a variable called "O_FILES" with the extension of "C_FILES" changed to ".o" is automatically created.

Change the output location of the object file

What does the "DEFINE" option describe?

  DEFINE =>'-o $@'

This is changing the output location of the object file. You can add gcc arguments using the option "DEFINE". And you can change the output destination of the object file by using the "-o" option of gcc.

What is "$@"? This is a Makefile syntax rule for variable to which the target name is automatically assigned. Since the target name is the object file name, if you write it like this, the object file will be output in the same directory as the source code file.

Linker targeting

Finally, you need to describe the targeting of the linker. You need to tell the linker the object file name, as all the object files will be merged into one and the final dynamic link library will end up with a ".so" extension.

To do this, specify:

    OBJECT =>'$(O_FILES)',

The list of object file names was in a variable called "O_FILES". To expand "O_FILES", write "$(O_FILES)".

The "OBJECT" option will then be automatically set to an option called "LDFROM" and passed to the linker.

Related Informatrion