1. Perl
  2. XS
  3. here

How to use Makefile.PL - From make to archive

Makefile.PL is a script that automatically generates a Makefile. Create XS module, Makefile.PL will be created automatically.

Here, we will explain the basic usage of Makefile.PL. If you want to know how to write Makefile.PL, please refer to the following article.

Basics of Makefile.PL

Makefile.PL is for automatically generating Makefile This is a script. Once you have created a Mekefile, you can compile the module with the make command.

Run Makefile.PL

Run Makefile.PL to generate a Makefile.

perl Makefile.PL

You can see that the Makefile is created in the directory.


Run make

Once the Makefile is generated, you can run the make command. make is used to compile C files and XS and prepare the module for installation.


When you run make, a directory called "blib" is created, in which the compiled dynamic link library and Perl modules are stored.


<h4>Run make test</h4>

When make is complete, you can run "make test". "Make test" is a command that automatically executes Perl's automatic test script in the "t" directory.

make test

Running "make test" will run the test script in the "t" directory.


By the way, even if you execute "make test" without doing make, make will be executed immediately before.

Please refer to the following article for how to write an automated test in Perl.

Run make install

You can use "make install" to install Perl modules.

make install

Installation is, in a nutshell, copying the required files to a location in the Perl library path.

I haven't used this command recently when installing. It is easier to install the "module.tar.gz" file using cpanm.

cpanm module .tar.gz

How to create a "module.tar.gz" file is explained below.

Run make manifest

You may want to upload your module to CPAN for distribution. In that case, the files to be included in the distribution must be included in the MANIFEST file.

You can use the "make manifest" command to automatically add the required files to the MANIFEST file.

make manifest

Unnecessary files can be added to MANIFEST by writing them in MANIFEST.SKIP . Below is an example of MANIFEST.SKIP. You can specify the file you want to skip with Regular expression.

^ Makefile $
^ Build $
^ Build.bat $
^ _ build/\. (Bak | tdy | old | tmp | BAK) $
~ $
^ blib/^pm_to_blib
\ .cvsignore
\ .gz $
^ cover_db/^MYMETA.yml $
^ MYMETA.json $
^ spvm $
^ solo/objs/</pre>

If you add the wrong file to MANIFEST, run "make manifest" again as "rm MANIFEST".

<h4>Run make disttest</h4>

After writing the file to be distributed to MANIFEST, it is necessary to confirm whether the test passes only with that file. If you execute "make disttest", the test will be executed using only the file specified in MANIFEST.

make disttest

Be sure to do it before distribution.

Run make dist

Run the "make dist" command to create an archive file for distribution.

make dist

The archive file is tarred, gzipped and has the extension "tar.gz".


The archive created in this way can be uploaded to CPAN.

Run make real clean

Use the "make real clean" command to delete generated files such as blib and Makefile.

make real clean

If you want to start over, use "make real clean". You can revert to the state before you ran "perl Makefile.PL".


Remembering the above eight commands is enough to make a CPAN release. It is summarized below.

  1. perl Makefile.PL
  2. make
  3. make test
  4. make install
  5. make manifest
  6. make disttest
  7. make dist
  8. make real clean

Makefile.PL technique

The following explains how to write Makefile.PL using ExtUtils::MakeMaker .

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.


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
| - Makefile.PL
| - 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
`- 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.

How to write XS module

Makefile.PL is often rewritten when writing an XS module. See Introduction to C/C ++ Binding with XS for how to create an XS module.

Related Informatrion