Name

SPVM::Builder::Config - Config for Compiling and Linking Native Classes

Description

The SPVM::Builder::Config class has methods to get and set config for compiling and linking native classes.

Usage

use SPVM::Builder::Config;

# Create a config
my $config = SPVM::Builder::Config->new(file => __FILE__);

# GNU C99
my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);

# C99
my $config = SPVM::Builder::Config->new_c99(file => __FILE__);

# C++
my $config = SPVM::Builder::Config->new_cpp(file => __FILE__);

# C++11
my $config = SPVM::Builder::Config->new_cpp11(file => __FILE__);

# C++17
my $config = SPVM::Builder::Config->new_cpp17(file => __FILE__);

# Optimize
$config->optimize("-O2");

# Optimize with debug mode
$config->optimize("-O0 -g");

# Add ccflags
$config->add_ccflag("-DFOO");

# Add source files
$config->add_source_file("foo.c", "bar.c", "baz/baz.c");

# Add libraries
$config->add_lib("gdi32", "d2d1", "Dwrite");

# Add ldflags
$config->add_ldflag("-pthread");

# Use resource
$config->use_resource("Resource::MyResource");

Fields

ext

my $ext = $config->ext;
$config->ext($ext);

Gets and sets the ext field, the extension of a native class.

Examples:

# MyClass.c
$config->ext('c');

# MyClass.cpp
$config->ext('cpp');

# MyClass.cc
$config->ext('cc');

# MyClass.cu
$config->ext('cu');

# MyClass.m
$config->ext('m');

cc

my $cc = $config->cc;
$config->cc($cc);

Gets and sets the cc field, a compiler name.

Examples:

# gcc
$config->cc('gcc');

# g++ for C++
$config->cc('g++');

# nvcc for CUDA/GUP
$config->cc('nvcc');

# cc that compiled this Perl
use Config;
$config->cc($Config{cc});

include_dirs

my $include_dirs = $config->include_dirs;
$config->include_dirs($include_dirs);

Gets and sets the include_dirs field, an array reference containing header file search directories.

The values of this field are converted to -I options when the arguments of the compiler "cc" are created.

# -I /path1 -I /path2
$config->include_dirs(['/path1', '/path2']);

spvm_core_include_dir

my $spvm_core_include_dir = $config->spvm_core_include_dir;
$config->spvm_core_include_dir($spvm_core_include_dir);

Gets and sets the spvm_core_include_dir field, an SPVM core header file search directory.

The value of this field is converted to -I option when the arguments of the compiler "cc" are created.

This field is automatically set and users nomally do not change it.

native_include_dir

my $native_include_dir = $config->native_include_dir;
$config->native_include_dir($native_include_dir);

Gets and sets the native_include_dir field, a native header file search directory.

The value of this field is converted to -I option when the arguments of the compiler "cc" are created.

This field is automatically set and users nomally do not change it.

native_src_dir

my $native_src_dir = $config->native_src_dir;
$config->native_src_dir($native_src_dir);

Gets and sets the native_src_dir field, a native source file search directory.

This field is automatically set and users nomally do not change it.

ccflags

my $ccflags = $config->ccflags;
$config->ccflags($ccflags);

Gets and sets the ccflags field, an array reference containing arugments of the compiler "cc".

dynamic_lib_ccflags

my $dynamic_lib_ccflags = $config->dynamic_lib_ccflags;
$config->dynamic_lib_ccflags($dynamic_lib_ccflags);

Gets and sets the dynamic_lib_ccflags field, an array reference containing arugments of the compiler "cc" for dynamic linking.

This field is automatically set and users nomally do not change it.

thread_ccflags

my $thread_ccflags = $config->thread_ccflags;
$config->thread_ccflags($thread_ccflags);

Gets and sets the thread_ccflags field, an array reference containing arugments of the compiler "cc" for threads.

This field is automatically set and users nomally do not change it.

mingw_ccflags

my $mingw_ccflags = $config->mingw_ccflags;
$config->mingw_ccflags($mingw_ccflags);

Gets and sets the mingw_ccflags field, an array reference containing arugments of the compiler "cc" for MinGW.

This field is automatically set and users nomally do not change it.

std

my $std = $config->std;
$config->std($std);

Gets and sets the std field, a language standard.

This field is converted to -std option when the arguments of the compiler "cc" are created.

Examples:

# -std=c99
$config->std('c99');

# -std=gnu99
$config->std('gnu99');

# -std=cpp
$config->std('cpp');

# -std=cpp11
$config->std('cpp11');

# -std=cpp17
$config->std('cpp17');

optimize

my $optimize = $config->optimize;
$config->optimize($optimize);

Gets and sets the optimize field, an arugment of the compiler "cc" for optimization.

Examples:

$config->optimize('-O3');
$config->optimize('-O2');
$config->optimize('-g3 -O0');

source_files

my $source_files = $config->source_files;
$config->source_files($source_files);

Gets and sets the source_files field, an array reference containing relative paths of native source file file from "native_src_dir" field.

after_create_compile_info_cbs

my $after_create_compile_info_cbs = $config->after_create_compile_info_cbs;
$config->after_create_compile_info_cbs($after_create_compile_info_cbs);

Gets and sets the after_create_compile_info_cbs field, an array reference containing callbacks called just after creating compilation information.

These callbacks are executed even if no object file was generated.

The 1th argument of the callback is an SPVM::Builder::Config object.

The 2th argument of the callback is an SPVM::Builder::CompileInfo object.

before_compile_cbs

my $before_compile_cbs = $config->before_compile_cbs;
$config->before_compile_cbs($before_compile_cbs);

Gets and sets the before_compile_cbs field, an array reference containing callbacks called just before the compile command "cc" is executed.

These callbacks are executed only if an object file is actually generated.

The 1th argument of the callback is an SPVM::Builder::Config object.

The 2th argument of the callback is an SPVM::Builder::CompileInfo object.

ld

my $ld = $config->ld;
$config->ld($ld);

Gets and sets the ld field, a linker name.

Examples:

$config->ld('gcc');
$config->ld('g++');

lib_dirs

my $lib_dirs = $config->lib_dirs;
$config->lib_dirs($lib_dirs);

Gets and sets the lib_dirs field, an array reference containing library search directories.

The values of this field are converted to -L options when the arguments of the linker "ld" are created.

# -L /path1 -L /path2
$config->lib_dirs(['/path1', '/path2']);

libs

my $libs = $config->libs;
$config->libs($libs);

Gets and sets the libs field, an array reference containing library names such as z, and png or SPVM::Builder::LibInfo objects.

The values of this field are converted to -l options when the arguments of the linker "ld" are created.

See "Library Path Resolution" about resolving library paths.

Examples:

# -l libz -l libpng
$config->libs(['z', 'png']);

ldflags

my ldflags = $config->ldflags;
$config->ldflags(ldflags);

Gets and sets the ldflags field, an array reference containing arguments of the linker "ld".

dynamic_lib_ldflags

my dynamic_lib_ldflags = $config->dynamic_lib_ldflags;
$config->dynamic_lib_ldflags(dynamic_lib_ldflags);

Gets and sets the dynamic_lib_ldflags field, an array reference containing arguments of the linker "ld" for dynamic libraries.

This field is automatically set and users nomally do not change it.

thread_ldflags

my thread_ldflags = $config->thread_ldflags;
$config->thread_ldflags(thread_ldflags);

Gets and sets the thread_ldflags field, an array reference containing arguments of the linker "ld" for threads.

This field is automatically set and users nomally do not change it.

static_lib_ldflag

my static_lib_ldflag = $config->static_lib_ldflag;
$config->static_lib_ldflag(static_lib_ldflag);

Gets and sets the static_lib_ldflag field, an array reference containing a pair of arguments to start statically linking and end it.

The library name added by the "add_static_lib" are surrounded by the values of the pair.

# -Wl,-Bstatic -llibfoo -Wl,-Bdynamic
$config->static_lib_ldflag(['-Wl,-Bstatic', '-Wl,-Bdynamic']);
$config->add_static_lib('foo');

This field is automatically set and users nomally do not change it.

This field only works correctly in Linux/Unix.

Mac does not support these options. If you want to search a static library, create a new library search directory, copy a static library to there, and add the new library search directory.

# /path_for_static_lib/libz.a
$config->add_lib_dir('/path_for_static_lib');
$config->add_lib('z');

MinGW on Windows supports these options, but instead of linking statically, it links dynamically with absolute paths. This is usually not the intended behavior. If you want to do static linking on Windows, you need to use --static option.

ld_optimize

my $ld_optimize = $config->ld_optimize;
$config->ld_optimize($ld_optimize);

Gets and sets the ld_optimize field, an argument of the linker "ld" for optimization.

Examples:

$config->ld_optimize("-O3");
my $after_create_link_info_cbs = $config->after_create_link_info_cbs;
$config->after_create_link_info_cbs($after_create_link_info_cbs);

Gets and sets the after_create_link_info_cbs field, an array reference containing callbacks called just after creating link information.

These callbacks are executed even if no dynamic link library file was generated.

The 1th argument of the callback is an SPVM::Builder::Config object.

The 2th argument of the callback is an SPVM::Builder::LinkInfo object.

my $before_link_cbs = $config->before_link_cbs;
$config->before_link_cbs($before_link_cbs);

Gets and sets the before_link_cbs field, an array reference containing callbacks called just before the link command "ld" is executed.

These callbacks are executed only if a dynamic link library is actually generated.

The 1th argument of the callback is an SPVM::Builder::Config object.

The 2th argument of the callback is an SPVM::Builder::LinkInfo object.

force

my $force = $config->force;
$config->force($force);

Gets and sets the force field.

If this field is a true value, the compilation and linking are forced.

If this field is a false value except for undef, the compilation and linking are performed following the rule of the dependency resolution.

If this field is undef, this config does not specify whether the compilation and linking are perfomed.

quiet

my $quiet = $config->quiet;
$config->quiet($quiet);

Gets and sets the quiet field.

If this field is a true value, the messages from the compiler and the linker are output to stderr.

If this field is a false value except for undef, the messages from the compiler and the linker are not output.

If this field is undef, this config does specify whether the messages from the compiler and the linker are output.

class_name

my $class_name = $config->class_name;
$config->class_name($class_name);

Gets and sets the class_name field, the name of the class configured by this config.

This field is automatically set and users nomally do not change it.

file

my $file = $config->file;
$config->file($file);

Gets and sets the file field, the file path of this config.

This field is set by "new" method and users nomally do not change it.

file_optional

my $file_optional = $config->file_optional;
$config->file_optional($file_optional);

Gets and sets the file_optional field.

If this field is a true value, even if the file field is not given to "new" method, the exception is not thrown.

output_type

my $output_type = $config->output_type;
$config->output_type($output_type);

Gets and sets the output_type field, a type of the output file "output_file" generated by the linker "ld".

If thie field is dynamic_lib, the output file is a dynamic link library.

If thie field is static_lib, the output file is a static link library.

If thie field is exe, the output file is an executable file.

This field is automatically set and users nomally do not change it.

no_compile_resource

my $no_compile_resource = $config->no_compile_resource;
$config->no_compile_resource($no_compile_resource);

Gets and sets the no_compile_resource field.

If this value is a true value, no native source files of resources loaded by "use_resource" method are compiled.

This field is automatically set and users nomally do not change it.

resource_loader_config

my $resource_loader_config = $config->resource_loader_config;
$config->resource_loader_config($resource_loader_config);

Gets and sets the resource_loader_config field, the config file of the class that loaded a resource by "use_resource" method.

This field is automatically set and users nomally do not change it.

category

my $category = $config->category;
$config->category($category);

Gets and sets the category field.

If this field is precompile, this config is for precompilation,

If this field is native, this config is for a native class.

This field is automatically set and users nomally do not change it.

config_exe

my $config_exe = $config->config_exe;
$config->config_exe($config_exe);

Gets and sets the config_exe field.

If spvmcc command generates an excutable file, this field is set to an SPVM::Builder::Config::Exe object.

This field is automatically set and users nomally do not change it.

cc_input_dir

my $cc_input_dir = $config->cc_input_dir;
$config->cc_input_dir($cc_input_dir);

Gets and sets the cc_input_dir field, an input directory for the compiler "cc".

This field is automatically set and users nomally do not change it.

cc_output_dir

my $cc_output_dir = $config->cc_output_dir;
$config->cc_output_dir($cc_output_dir);

Gets and sets the cc_output_dir field, an output directory for the compiler "cc".

This field is automatically set and users nomally do not change it.

output_dir

my $output_dir = $config->output_dir;
$config->output_dir($output_dir);

Gets and sets the output_dir field, an output directory for the linker "ld".

This field is automatically set and users nomally do not change it.

output_file

my $output_file = $config->output_file;
$config->output_file($output_file);

Gets and sets the output_file field. A path of a dinamic link library or an executable file generated by the linker "ld".

This field is automatically set and users nomally do not change it.

used_as_resource

my $used_as_resource = $config->used_as_resource;
$config->used_as_resource($used_as_resource);

Gets and sets the used_as_resource field.

If this field is true, this config is used as a resource.

This field is automatically set and users nomally do not change it.

Class Methods

new

my $config = SPVM::Builder::Config->new(%fields);

Creates a new SPVM::Builder::Config object with fields, and returns it.

The file field must be defined.

Field Default Values:

Exceptions:

The "file" field must be defined. Otherwise, an exception is thrown.

Exampels:

my $config = SPVM::Builder::Config->new(file => __FILE__);

new_c

my $config = SPVM::Builder::Config->new_c(file => __FILE__);

Calls "new" method and sets "ext" field to c, and returns the return value of "new" method.

new_gnu99

my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);

Calls "new_c" method and sets "std" field to gnu99, and returns the return value of "new_c" method.

new_gnu11

my $config = SPVM::Builder::Config->new_gnu11(file => __FILE__);

Calls "new_c" method and sets "std" field to gnu11, and returns the return value of "new_c" method.

new_c99

my $config = SPVM::Builder::Config->new_c99(file => __FILE__);

Calls "new_c" method and sets "std" field to c99, and returns the return value of "new_c" method.

new_c11

my $config = SPVM::Builder::Config->new_c11(file => __FILE__);

Calls "new_c" method and sets "std" field to c11, and returns the return value of "new_c" method.

new_cpp

my $config = SPVM::Builder::Config->new_cpp(file => __FILE__);

Calls "new" method and sets "ext" field to cpp and sets "cc" field to a C++ compiler and sets "ld" field to a C++ linker, and returns the return value of "new" method.

If $Config{gccversion} contains clang, "cc" field and "ld" field are set to clang++. Otherwise, "cc" field and "ld" field are set to g++.

new_cpp11

my $config = SPVM::Builder::Config->new_cpp11(file => __FILE__);

Calls "new_cpp" method and sets "std" field to c++11, and returns the return value of "new_cpp" method.

new_cpp14

my $config = SPVM::Builder::Config->new_cpp14(file => __FILE__);

Calls "new_cpp" method and sets "std" field to c++14, and returns the return value of "new_cpp" method.

new_cpp17

my $config = SPVM::Builder::Config->new_cpp17(file => __FILE__);

Calls "new_cpp" method and sets "std" field to c++17, and returns the return value of "new_cpp" method.

Instance Methods

add_ccflag

$config->add_ccflag(@ccflags);

Adds @ccflags to the end of "ccflags" field.

add_ldflag

$config->add_ldflag(@ldflags);

Adds @ldflags to the end of "ldflags" field.

add_include_dir

$config->add_include_dir(@include_dirs);

Adds @include_dirs to the end of "include_dirs" field.

add_source_file

$config->add_source_file(@source_files);

Adds @source_files to the end of "source_files" field.

Examples:

$config->add_source_file('foo.c', 'bar.c');

add_after_create_compile_info_cb

$config->add_after_create_compile_info_cb(@after_create_compile_info_cbs);

Adds @after_create_compile_info_cbs to the end of "after_create_compile_info_cbs" field.

Examples:

$config->add_after_create_compile_info_cb(sub {
  my ($config, $compile_info) = @_;
  
  my $cc = $config->cc;
  
  # Do something
});

add_before_compile_cb

$config->add_before_compile_cb(@before_compile_cbs);

Adds @before_compile_cbs to the end of "before_compile_cbs" field.

Examples:

$config->add_before_compile_cb(sub {
  my ($config, $compile_info) = @_;
  
  my $cc_command = $compile_info->to_command;
  
  # Do something
});

add_lib_dir

$config->add_lib_dir(@lib_dirs);

Adds @lib_dirs to the end of "lib_dirs" field.

add_lib

$config->add_lib(@libs);

Adds @libs to the end of "libs" field.

Examples:

$config->add_lib('gsl');
$config->add_lib('gsl', 'z');
$config->add_lib(
  SPVM::Builder::LibInfo->new(config => $config, name => 'gsl'),
  SPVM::Builder::LibInfo->new(config => $config, name => 'z', is_abs => 1),
);

add_lib_abs

$config->add_lib_abs(@libs);

Adds @libs to the end of "libs" field with SPVM::Builder::LibInfo#is_abs field set to a true value.

If a value in @libs is not an SPVM::Builder::LibInfo object, an SPVM::Builder::LibInfo object is created from the library name.

If the library is located in your user directory, it is good to use "add_lib_abs" method instead of "add_lib" method.

This is because if the generated dynamic link library has a relative path, that path cannot be resolved when it is loaded.

For system libraries, there is no problem because the linker knows the search directory for the library.

add_static_lib

$config->add_static_lib(@libs);

Adds @libs to the end of "libs" field with SPVM::Builder::LibInfo#is_static field set to a true value.

If a value in @libs is not an SPVM::Builder::LibInfo object, an SPVM::Builder::LibInfo object is created from the library name.

Examples:

$config->add_static_lib('gsl');
$config->add_static_lib('gsl', 'z');

add_static_lib_abs

$config->add_static_lib_abs(@libs);

Adds @libs to the end of "libs" field with SPVM::Builder::LibInfo#is_static field and SPVM::Builder::LibInfo#is_abs field set to a true value.

If a value in @libs is not an SPVM::Builder::LibInfo object, an SPVM::Builder::LibInfo object is created from the library name.

$config->add_before_link_cb(@before_link_cbs);

Adds @before_link_cbs to the end of "before_link_cbs" field.

Examples:

$config->add_before_link_cb(sub {
  my ($config, $link_info) = @_;
  
  my $object_files = $link_info->object_files;
  
  # Do something
  
});

use_resource

my $resource = $config->use_resource($resource_name);
my $resource = $config->use_resource($resource_name, %options);

Loads a resource given a resource name and options, and returns it. The return value is an SPVM::Builder::Resource object.

Options:

Examples:

$config->use_resource('Resource::MyResource');
$config->use_resource('Resource::MyResource', mode => 'mode1', argv => ["option1_name" => "option1_value"]);

get_resource

my $resource = $config->get_resource($resource_name);

Gets a resource loaded by "use_resource" method given a resource name, and returns it. The return value is an SPVM::Builder::Resource object.

get_resource_names

my $resource_names = $config->get_resource_names;

Returns resource names loaded by "use_resource" method.

load_config

my $config = $config->load_config($config_file, $argv);

Loads a config file given a config file path and an array refernce containing config arguments, and returns an SPVM::Builder::Config object.

The values referenced by $argv is set to the @ARGV of the config file.

Examples:

my $config = $config->load_config(__FILE__, \@ARGV);

my $config = $config->load_config(__FILE__, []);

load_base_config

my $config = $config->load_base_config($config_file, $argv);

Creates the base config file path from the config file path $config_file, and calls "load_config" method given the base config file path and config arguments, and returns its return value.

A base config file is the config file that removes its mode.

# Config file
MyClass.mode.config

# Base config file
MyClass.config

Examples:

my $config = SPVM::Builder::Config::Exe->load_base_config(__FILE__);

load_mode_config

my $config = $config->load_mode_config($config_file, $mode, $argv);

Creates a mode config file path from the config file path $config_file, and calls "load_config" method given the mode config file path and config arguments, and returns its return value.

my $config = SPVM::Builder::Config::Exe->load_mode_config(__FILE__, "production");

get_loaded_config_files

Returns the config files loaded by "load_config" method.

clone

my $clone = $self->clone;

Clones SPVM::Builder::Config object, and returns it.

Config Mode

A config can have its mode if the config is one for an executable file generated by spvmcc command and for a resource.

The mode is written in the format .MODE_NAME just before the .config extension of a config file.

MODE_NAME must consist of a-zA-Z0-9_.

Examples:

# production mode
MyClass.production.config

# devel mode
MyClass.devel.config

Use "mode" field to get the config mode.

my $modle = $config->mode;

SPVM::Builder::Config#use_resource method has mode option for giving a config mode.

$config->use_resource('Resource::MyResource', mode => 'production');

The spvmcc command has --mode option for giving a config mode.

spvmcc -o myapp --mode production myapp.spvm

Config Arguments

A config file can receive its argments.

Key-value pairs are recommended as the values of @ARGV because they are normally assigned to a Perl hash.

my %options = @ARGV;

my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);

SPVM::Builder::Config#use_resource method has argv option for giving config arguments.

$config->use_resource('Resource::MyResource', argv => [option_name => "option_value"]);

The spvmcc command has --config-argv option(released in the near future) for giving config arguments.

spvmcc -o myapp --config-argv option_name --config-argv option_value myapp.spvm

The spvmcc command also has --config-argv-option option(released in the near future) to write config arguments easily.

spvmcc -o myapp --config-argv-option option_name=option_value myapp.spvm

Library Path Resolution

The following is the rule of library path resolution.

Library names are converted to SPVM::Builder::LibInfo objects.

If SPVM::Builder::LibInfo#is_abs field is a false value, the linker "ld" resolves libaray paths.

If SPVM::Builder::LibInfo#is_abs field is a true value, libaray paths are resolved by the following rules.

A library is searched in the library search directories contained in "lib_dir" field from the beginning.

If SPVM::Builder::LibInfo#is_static field is a false value, the search is performed in the order of a dynamic library, a static library.

If SPVM::Builder::LibInfo#is_static field is a true value, the search is performed only in static libraries.

If a library is found, -l option of the linker "ld" is created using the found absolute path.

Examples

GNU C99:

my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);

C99:

my $config = SPVM::Builder::Config->new_c99(file => __FILE__);

C11:

my $config = SPVM::Builder::Config->new_c11(file => __FILE__);

C++:

my $config = SPVM::Builder::Config->new_cpp(file => __FILE__);

C++11:

my $config = SPVM::Builder::Config->new_cpp11(file => __FILE__);

Output messages to stderr from the compiler and the linker:

$config->quiet(0);

Force the compilation and link:

$config->force(1);

Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License