📄 mex.pl
字号:
$bin_extension = $NAME_OUTPUT;
$bin_extension =~ s/\"//g;
$bin_extension =~ s/.*\.([^.]*)$/\1/;
if ($verbose) {
if ($main::mbuild eq "no") {
&describe("final_options");
} else {
&describe_mb("final_options");
}
}
if ($COMPILER eq "none") {
if ($main::mbuild eq "no") {
&describe("invalid_options_file");
} else {
&describe_mb("invalid_options_file");
}
}
# WATCOM Compiler can't handle MATLAB installations with spaces in
# path names.
if ($COMPILER =~ /(wpp)|(wcc)|(wcl)/ && $MATLAB =~ " ")
{
&expire("You have installed MATLAB into a directory whose name contains spaces. " .
"The WATCOM compiler cannot handle that. Either rename your MATLAB " .
"directory (currently $MATLAB) or run mex -setup and select a " .
"different compiler.");
}
if ($outdir_flag && $NAME_OBJECT eq "") {
if ($main::mbuild eq "no") {
&describe("outdir_missing_name_object");
} else {
&describe_mb("outdir_missing_name_object");
}
}
# check that MATLAB or the C/C++ Math Library is where it is expected to be
if ( ! -e "$MATLAB\\extern\\include\\matrix.h" ) {
if ($main::mbuild eq "no") {
&expire("Error: The variable MATLAB in \"mex.bat\" was not set properly.\n" .
" Please modify this variable at the top of the file " .
"\"mex.bat\".\n\n MATLAB is currently set to $MATLAB");
} else {
&expire("Error: Cannot find the MATLAB C/C++ Math Library on your path. " .
"Please check your path or re-install the C/C++ Math Library.");
}
}
#######################################################################
# Determine final values
#######################################################################
# Decide how to optimize or debug
if (! $debug) { # Normal case
$FLAGS = "$OPTIMFLAGS";
$LINKFLAGS = "$LINKFLAGS $LINKOPTIMFLAGS";
} elsif (! $optimize) { # Debug; don't optimize
$FLAGS = "$DEBUGFLAGS";
$LINKFLAGS = "$LINKDEBUGFLAGS $LINKFLAGS ";
} else { # Debug and optimize
$FLAGS = "$DEBUGFLAGS $OPTIMFLAGS";
$LINKFLAGS = "$LINKDEBUGFLAGS $LINKFLAGS $LINKOPTIMFLAGS ";
}
# Include the simulink include directory if it exists
#
my ($simulink_inc_dir) = '';
$simulink_inc_dir = "-I$ML_DIR\\simulink\\include"
if (-e "$MATLAB\\simulink\\include");
# Add extern/include to the path (it always exists)
$FLAGS = "-I$ML_DIR\\$mex_include_dir $simulink_inc_dir $FLAGS"
unless ($fortran);
# Add inlining if switch was set
$FLAGS = "$FLAGS -DARRAY_ACCESS_INLINING" if ( $inline );
# If there are no files, then exit.
#
if ( ! @FILES ) {
if ($main::mbuild eq "no"){
&describe("usage");
} else {
&describe_mb("usage");
}
&expire("Error: No file names given.");
}
# If we are checking arguments, add $MATLAB/extern/src/mwdebug.c
# to source file list.
push(@FILES, "$MATLAB\\extern\\src\\mwdebug.c") if ($argcheck eq "yes");
#######################################################################
# Verify that compiler binary exists
#######################################################################
$COMPILER_DIR = &search_path("$COMPILER.exe");
if ( ! $COMPILER_DIR ) {
if ($main::mbuild eq "no") {
&describe("compiler_not_found");
} else {
&describe_mb("compiler_not_found");
}
&expire("Error: Unable to locate compiler.");
}
#######################################################################
# Prepare makefile
#######################################################################
if ($makefilename)
{
open(MAKEFILE, ">>$makefilename")
|| &expire("Error: Cannot append to file '$makefilename': $!");
# Emit main dependency rule
print MAKEFILE "bin_target : $ENV{'OUTDIR'}$ENV{'MEX_NAME'}.$bin_extension\n\n";
}
#######################################################################
# Compile source files
#######################################################################
# Loop over @FILES to compile each file. Keep files we actually
# compile separate from the ones we don't compile but need to link.
# This way, we can later clean up all .obj files we created.
for (;$_=shift(@FILES);) {
($FILENAME, $EXTENSION) = (/([ \w]+)\.(\w*)$/);
if ($EXTENSION =~ /(c|f|cc|cxx|cpp|for|f90)$/i ) {
my ($target_name, $name_arg);
if ($NAME_OBJECT) {
$target_name = "$ENV{'OUTDIR'}$FILENAME.obj";
$name_arg = $NAME_OBJECT . &smart_quote($target_name);
}
else {
$target_name = "$FILENAME.obj";
$name_arg = "";
}
my ($args) =
"$ARG_FLAGS $COMPFLAGS $name_arg $FLAGS " . &smart_quote($_);
if (!$makefilename)
{
my $messages = RunCmd("$COMPILER $args");
# Check for error; $? might not work, so also check for resulting file
if ($? != 0 || !(-e "$target_name" || $main::no_execute)) {
print "$messages" unless $verbose; # verbose => printed in RunCmd
&expire("Error: Compile of '$_' failed.");
}
if (!$compile_only)
{
push(@FILES_TO_REMOVE, "$target_name");
}
}
else
{
# Emit compile dependency rule
print MAKEFILE &smart_quote($target_name) . " : " . &smart_quote($_);
print MAKEFILE "\n\t$COMPILER $args\n\n";
}
push(@FILES_TO_LINK, "$LINK_FILE " . &smart_quote($target_name));
push(@FILES_TO_LINK_BASE, &smart_quote($target_name));
}
elsif ($EXTENSION =~ /lib$/i)
{
push(@FILES_TO_LINK, "$LINK_LIB " . &smart_quote($_));
push(@FILES_TO_LINK_BASE, &smart_quote($_));
}
else
{
push(@FILES_TO_LINK, "$LINK_FILE " . &smart_quote($_));
push(@FILES_TO_LINK_BASE, &smart_quote($_));
}
}
&expire("normally") if ($compile_only);
#######################################################################
# Perform prelink tasks
#######################################################################
if ($makefilename)
{
# Emit link dependency rule
print MAKEFILE "$ENV{'OUTDIR'}$ENV{'MEX_NAME'}.$bin_extension";
print MAKEFILE " : @FILES_TO_LINK_BASE\n";
}
#
# Note that error checking is not possible; we don't get a return
# status, and there's no way of knowing a priori what each task is
# supposed to do.
(@PRELINK_CMDS) = split(/;/,$PRELINK_CMDS);
while ($PRELINK_CMDS = shift(@PRELINK_CMDS)) {
# Skip if $PRELINK_CMDS is only whitespace
next if (!($PRELINK_CMDS =~ /\S/));
if (!$makefilename)
{
RunCmd($PRELINK_CMDS);
}
else
{
print MAKEFILE "\t$PRELINK_CMDS\n";
}
}
# There can be multiple prelink command lines called, PRELINK_CMDS1, 2 etc.
# so loop through dealing with each.
my $i = 1;
while ( my $prelink = $ENV{"PRELINK_CMDS$i"} ) {
if (!$makefilename)
{
RunCmd($prelink);
}
else
{
print MAKEFILE "\t$prelink\n";
}
$i++;
$prelink =$ENV{"PRELINK_CMDS".$i};
}
my $i = 1;
while ( my $prelink = $ENV{"PRELINK_CMDS_HG$i"} ) {
if (!$makefilename)
{
RunCmd($prelink);
}
else
{
print MAKEFILE "\t$prelink\n";
}
$i++;
$prelink =$ENV{"PRELINK_CMDS_HG".$i};
}
# If DLL_MAKEDEF is set, and we are targeting a DLL, execute it
if ($link eq "shared")
{
$i = 0;
my $makedef = $ENV{"DLL_MAKEDEF"};
while ($makedef =~ /\S/)
{
if ($makefilename)
{
print MAKEFILE "\t$makedef\n";
}
RunCmd($makedef);
$i++;
$makedef = $ENV{"DLL_MAKEDEF" . $i};
}
}
push(@FILES_TO_REMOVE,
("$ENV{'MEX_NAME'}lib.exp"), ("$ENV{'MEX_NAME'}lib.lib"));
push(@FILES_TO_REMOVE, ("$ENV{'MEX_NAME'}.bak"));
#######################################################################
# If there is a resource compiler, compile resource now
if ($RC_COMPILER =~ /\S/) {
my ($rc_line) = '';
$rc_line .= " -DARRAY_ACCESS_INLINING" if ($inline);
$rc_line .= " -DV4_COMPAT" if ($v4);
$rc_line .= " \"$ENV{'MATLAB'}\\extern\\include\\mexversion.rc\"";
if (!$makefilename)
{
my $messages = RunCmd("$RC_COMPILER $rc_line");
# Check for error; $? might not work, so also check for string "error"
if ($? != 0 || $messages =~ /\b(error|fatal)\b/i) {
print "$messages" unless $verbose; # verbose => printed out in RunCmd
&expire("Error: Resource compile of 'mexversion.rc' failed.");
}
push(@FILES_TO_REMOVE, "$ENV{'OUTDIR'}mexversion.res");
}
else
{
print MAKEFILE "\t$RC_COMPILER $rc_line\n";
}
push(@FILES_TO_LINK, &smart_quote("$ENV{'OUTDIR'}mexversion.res"));
}
#######################################################################
# Link files
#######################################################################
#
# NAME_OUTPUT always goes in the list, but it may be blank (in which
# case it's harmless to put it in). Leaving the variable blank is
# equivalent to assuming that the output will be named after the
# first object file in the list.
my ($ARGS);
if ( $ENV{'RSP_FILE_INDICATOR'} )
{
my $response_file;
if ($makefilename)
{
$response_file = "$ENV{'OUTDIR'}$ENV{'MEX_NAME'}_master.rsp";
}
else
{
$response_file = "$ENV{'OUTDIR'}$$\_tmp.rsp";
}
open(RSPFILE, ">$response_file") || &expire("Error: Can't open file '$response_file': $!");
push(@FILES_TO_REMOVE, "$response_file") if (!$makefilename);
print RSPFILE " @FILES_TO_LINK";
close(RSPFILE);
$ARGS = "$NAME_OUTPUT $LINKFLAGS " .
&smart_quote("$ENV{'RSP_FILE_INDICATOR'}$response_file") .
" $LINKFLAGSPOST";
if ($verbose && !$makefilename)
{
print " Contents of $response_file:\n";
print " @FILES_TO_LINK\n\n";
}
}
else
{
$ARGS = "$NAME_OUTPUT $LINKFLAGS @FILES_TO_LINK $LINKFLAGSPOST";
}
if (!$makefilename)
{
my $messages = RunCmd("$LINKER $ARGS");
# Check for error; $? might not work, so also check for resulting file
if ($? != 0 || !(-e "$ENV{'OUTDIR'}$ENV{'MEX_NAME'}.$bin_extension" || $main::no_execute ))
{
print "$messages" unless $verbose; # verbose => printed in RunCmd
&expire("Error: Link of '$ENV{'OUTDIR'}$ENV{'MEX_NAME'}.$bin_extension' failed.");
}
# If we got a file, make sure there were no errors
if ($messages =~ /\b(error|fatal)\b/i) {
print "$messages" unless $verbose; # verbose => printed in RunCmd
&expire("Error: Link of '$ENV{'OUTDIR'}$ENV{'MEX_NAME'}.$bin_extension' failed.");
}
if ($COMPILER =~ /bcc/ && $debug ne "yes")
{
push(@FILES_TO_REMOVE, "$ENV{'OUTDIR'}$ENV{'MEX_NAME'}.tds");
}
}
else
{
print MAKEFILE "\t$LINKER $ARGS\n";
}
#
# If a resource linker has been defined, use it
#
if ($RC_LINKER =~ /\S/) {
my $rc_line = "$ENV{'MATLAB'}\\extern\\include\\mexversion.rc " .
&smart_quote("$ENV{'OUTDIR'}$ENV{'MEX_NAME'}.$bin_extension");
$rc_line = "$rc_line -DARRAY_ACCESS_INLINING" if ($inline);
$rc_line = "$rc_line -DV4_COMPAT" if ($v4);
if (!$makefilename)
{
m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -