Browse Source
Add the support files for co-simulation with Verilog code
Add the support files for co-simulation with Verilog code
compiled by Verilator. Also add script files to Visual Studio builds that are already installed by the Makefile builds.pre-master-46
11 changed files with 689 additions and 13 deletions
-
10examples/xspice/verilator/README.txt
-
103examples/xspice/verilator/adc.cir
-
45examples/xspice/verilator/adc.v
-
12src/xspice/Makefile.am
-
1src/xspice/verilog/MSVC.CMD
-
3src/xspice/verilog/README.txt
-
13src/xspice/verilog/verilator_main.cpp
-
157src/xspice/verilog/verilator_shim.cpp
-
316src/xspice/verilog/vlnggen
-
21visualc/make-install-vngspice.bat
-
21visualc/make-install-vngspiced.bat
@ -0,0 +1,10 @@ |
|||
The circuit adc.cir in this directory illustrates the use of the d_cosim |
|||
XSPICE code model as a container for a Verilog simulation. Before the |
|||
simulation can be run, the Verilog code must be compiled by Verilator |
|||
using the command: |
|||
|
|||
ngspice vlnggen adc.v |
|||
|
|||
That should create a shared library file, adc.so (or adc.DLL on Windows) |
|||
that will be loaded by the d_cosim code model. The compiled Verilog code that |
|||
it contains will be executed during simulation. |
|||
@ -0,0 +1,103 @@ |
|||
Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim |
|||
|
|||
.subckt sar_adc input vref start valid d5 d4 d3 d2 d1 d0 clk |
|||
|
|||
* A transmission gate connects the input to the capacitor set. |
|||
|
|||
xsample input iin sample vref tgate |
|||
rin iin test_v 1k |
|||
|
|||
* Capacitors and controlling inverters |
|||
|
|||
xb5 test_v vref d5 ccap c=1p |
|||
xb4 test_v vref d4 ccap c={1p / 2} |
|||
xb3 test_v vref d3 ccap c={1p / 4} |
|||
xb2 test_v vref d2 ccap c={1p / 8} |
|||
xb1 test_v vref d1 ccap c={1p / 16} |
|||
xb0 test_v vref d0 ccap c={1p / 32} |
|||
clast test_v 0 {1p / 32} |
|||
|
|||
* An XSPICE ADC bridge functions as a comparator. |
|||
|
|||
acomp [%vd(test_v vref)] [comp] comparator |
|||
.model comparator adc_bridge in_low=0 in_high=0 |
|||
|
|||
* The digital portion of the circuit is specified in compiled Verilog. |
|||
* Outputs inverted to cancel the inverter in subcircuit ccap, |
|||
* and produce the correct numerical output value. |
|||
|
|||
adut [ Clk Comp Start] [Sample Valid ~d5 ~d4 ~d3 ~d2 ~d1 ~d0] null dut |
|||
.model dut d_cosim simulation="./adc.so" |
|||
.ends // SUBCKT sar_adc |
|||
|
|||
* Some MOS transistors complete the circuit. |
|||
* Models from https://homepages.rpi.edu/~sawyes/AIMSPICE_TutorialManual.pdf |
|||
|
|||
.model p1 pmos |
|||
+ level=2 vto=-0.5 kp=8.5e-6 gamma=0.4 phi=0.65 lambda=0.05 xj=0.5e-6 |
|||
.model n1 nmos |
|||
+ level=2 vto=0.5 kp=24e-6 gamma=0.15 phi=0.65 lambda=0.015 xj=0.5e-6 |
|||
|
|||
* Use those for an inverter. |
|||
|
|||
.subckt ainv in out vdd |
|||
mn out in 0 0 n1 |
|||
mp out in vdd vdd p1 |
|||
.ends |
|||
|
|||
* A transmission gate modelled by a switch. |
|||
|
|||
.subckt mos_tgate a b ctl vdd |
|||
mn a ctl b b n1 |
|||
xinv ctl ictl vdd ainv |
|||
mp b ictl a a p1 |
|||
.ends |
|||
|
|||
.subckt tgate a b ctl vdd |
|||
switch a b ctl 0 tg |
|||
.model tg sw vt=1.5 ron=2k |
|||
.ends |
|||
|
|||
* The per-bit subcircuit in the adc |
|||
|
|||
.subckt ccap in vcc ctl c=10p |
|||
xinv ctl tail vcc ainv |
|||
cb in tail {c} |
|||
.ends |
|||
|
|||
**** End of the ADC and its subcircuits. Begin test circuit **** |
|||
|
|||
.param vcc=3.3 |
|||
vcc vcc 0 {vcc} |
|||
|
|||
* Digital clock signal |
|||
|
|||
aclock 0 clk clock |
|||
.model clock d_osc cntl_array=[-1 1] freq_array=[1Meg 1Meg] |
|||
|
|||
* A simple DAC so that the result may be compared to the input. |
|||
|
|||
r5 d5 sum 2 |
|||
r4 d4 sum 4 |
|||
r3 d3 sum 8 |
|||
r2 d2 sum 16 |
|||
r1 d1 sum 32 |
|||
r0 d0 sum 64 |
|||
|
|||
vamm sum 0 0 |
|||
|
|||
* Pulse the Start signal high for 1.3uS each 10uS |
|||
|
|||
Vpulse Start 0 PULSE 0 {vcc} 0.2u 10n 10n 1.3u 10u |
|||
Vtest input 0 PULSE 0 3 0 200u 200u 1u 401u |
|||
|
|||
* The ADC for testing |
|||
|
|||
xtest input vcc start valid d5 d4 d3 d2 d1 d0 clk sar_adc |
|||
|
|||
|
|||
.control |
|||
tran 100n 250u |
|||
plot input xtest.test_v vamm#branch clk/2 start/3 xtest.sample/3 valid |
|||
.endc |
|||
.end |
|||
@ -0,0 +1,45 @@ |
|||
// Digital control for a successive approximation ADC with switched capacitors. |
|||
|
|||
module adc(Clk, Comp, Start, Sample, Done, Result); |
|||
input wire Clk, Comp, Start; |
|||
output reg Sample, Done; |
|||
output reg [Bits - 1 : 0] Result; |
|||
|
|||
parameter Bits=6; |
|||
|
|||
reg [Bits - 1 : 0] SR; |
|||
reg Running; |
|||
|
|||
initial begin |
|||
$display("ADC simulation starting"); |
|||
Done = 0; |
|||
Sample = 0; |
|||
Result = 0; |
|||
Running = 0; |
|||
end |
|||
|
|||
always @(posedge(Clk)) begin |
|||
if (Running) begin |
|||
if (Sample) begin |
|||
Sample <= 0; |
|||
SR[Bits - 1] = 1; |
|||
Result[Bits - 1] = 1; |
|||
end else if (SR != 0) begin |
|||
if (Comp) |
|||
Result &= ~SR; |
|||
SR >>= 1; |
|||
Result |= SR; |
|||
if (SR == 0) begin |
|||
Running <= 0; |
|||
Done <= 1; |
|||
end |
|||
end |
|||
end else if (Start) begin |
|||
Running <= 1; |
|||
Sample <= 1; |
|||
Done <= 0; |
|||
SR = 0; |
|||
Result = 0; |
|||
end |
|||
end |
|||
endmodule |
|||
@ -0,0 +1 @@ |
|||
CL /O2 /LD /EHsc /Fe..\adc.DLL /I. /IC:\mingw64\share\verilator\include\vltstd /IC:\mingw64\share\verilator\include Vlng__ALL.cpp verilator_shim.cpp C:\mingw64\share\verilator\include\verilated.cpp C:\mingw64\share\verilator\include\verilated_threads.cpp /link /DLL /EXPORT:Cosim_setup |
|||
@ -0,0 +1,3 @@ |
|||
This directory contains Ngspice scripts and other files used to prepare |
|||
Verilog (and possibly VHDL) code to be included in an Ngspice simulation. |
|||
An example circuit can be found in examples/xspice/verilator. |
|||
@ -0,0 +1,13 @@ |
|||
/* Dummy main() for Verilator. */ |
|||
|
|||
#include "ngspice/cmtypes.h" // For Digital_t
|
|||
#include "ngspice/cosim.h" // For struct co_info and prototypes
|
|||
|
|||
int main(int argc, char** argv, char**) { |
|||
struct co_info info; |
|||
|
|||
Cosim_setup(&info); |
|||
for (;;) |
|||
(*info.step)(&info); |
|||
return 0; |
|||
} |
|||
@ -0,0 +1,157 @@ |
|||
/* This is a very mangled version of Vadc__main.cpp as generated by Verilator. */ |
|||
|
|||
// Verilated -*- C++ -*-
|
|||
// DESCRIPTION: main() calling loop, created with Verilator --main
|
|||
|
|||
#include "verilated.h"
|
|||
#include "Vlng.h"
|
|||
|
|||
#include "ngspice/cmtypes.h" // For Digital_t
|
|||
#include "ngspice/cosim.h" // For struct co_info and prototypes
|
|||
|
|||
//======================
|
|||
|
|||
/* Structure for the input table. */ |
|||
|
|||
struct input { |
|||
const char *name; |
|||
unsigned int offset; |
|||
unsigned int count; |
|||
}; |
|||
|
|||
/* This VL_DATA macro is used in header files inputs.h, outputs.h and inouts.h
|
|||
* to write functions accept_input() and step(). |
|||
* The macro is used several times with different definitions. |
|||
*/ |
|||
|
|||
/* Generate the previous values table used by step(). */ |
|||
|
|||
#define VL_DATA(size, name, msb, lsb) + msb - lsb + 1
|
|||
static const unsigned int outs = 0 |
|||
#include "outputs.h"
|
|||
; |
|||
static const unsigned int inouts = 0 |
|||
#include "inouts.h"
|
|||
; |
|||
|
|||
static unsigned char previous_output[outs + inouts]; |
|||
|
|||
#undef VL_DATA
|
|||
|
|||
/* The input function: it should ignore out-of-range values of index. */ |
|||
|
|||
#define VL_DATA(size, name, msb, lsb) \
|
|||
if (index >= msb - lsb + 1) { \ |
|||
index -= msb - lsb + 1; \ |
|||
} else if (msb == 0 && lsb == 0) { \ |
|||
topp->name = val ? 1 : 0; \ |
|||
return; \ |
|||
} else { \ |
|||
if (val) \ |
|||
topp->name |= (1 << (msb - index)); \ |
|||
else \ |
|||
topp->name &= (1 << (msb - index)); \ |
|||
return; \ |
|||
} |
|||
|
|||
static void accept_input(struct co_info *pinfo, |
|||
unsigned int index, Digital_t *vp) |
|||
{ |
|||
Vlng *topp = (Vlng *)pinfo->handle; |
|||
unsigned int val, offset; |
|||
|
|||
val = vp->state; |
|||
if (val == UNKNOWN) |
|||
return; // Verilator simulations are two-state.
|
|||
|
|||
#include "inputs.h"
|
|||
|
|||
/* For inout ports the new value must be stored to detect changes. */ |
|||
|
|||
offset = outs; |
|||
#undef VL_DATA
|
|||
#define VL_DATA(size, name, msb, lsb) \
|
|||
if (index >= msb - lsb + 1) { \ |
|||
index -= msb - lsb + 1; \ |
|||
offset += msb - lsb + 1; \ |
|||
} else if (msb == 0 && lsb == 0) { \ |
|||
topp->name = val ? 1 : 0; \ |
|||
previous_output[index + offset] = val; \ |
|||
return; \ |
|||
} else { \ |
|||
if (val) \ |
|||
topp->name | (1 << (msb - index)); \ |
|||
else \ |
|||
topp->name &= (1 << (msb - index)); \ |
|||
previous_output[index + offset] = val; \ |
|||
return; \ |
|||
} |
|||
|
|||
#include "inouts.h"
|
|||
} |
|||
#undef VL_DATA
|
|||
|
|||
/* The step function that calls the Verilator code. */ |
|||
|
|||
#define VL_DATA(size, name, msb, lsb) \
|
|||
for (i = msb; i >= lsb; --i) { \ |
|||
if (topp->name & (1 << i)) \ |
|||
bit = 1; \ |
|||
else \ |
|||
bit = 0; \ |
|||
if (bit ^ previous_output[index]) { \ |
|||
previous_output[index] = bit; \ |
|||
oval.state = (Digital_State_t)bit; \ |
|||
(*pinfo->out_fn)(pinfo, index, &oval); \ |
|||
} \ |
|||
++index; \ |
|||
} |
|||
|
|||
static void step(struct co_info *pinfo) |
|||
{ |
|||
static Digital_t oval = {ZERO, STRONG}; |
|||
Vlng *topp; |
|||
int index, i; |
|||
unsigned char bit; |
|||
|
|||
topp = (Vlng *)pinfo->handle; |
|||
topp->eval(); |
|||
|
|||
/* Now scan the outputs for changes. */ |
|||
|
|||
index = 0; |
|||
#include "outputs.h"
|
|||
#include "inouts.h"
|
|||
} |
|||
#undef VL_DATA
|
|||
|
|||
extern "C" void Cosim_setup(struct co_info *pinfo) |
|||
{ |
|||
int i; |
|||
|
|||
// Setup context, and defaults
|
|||
|
|||
Verilated::debug(0); |
|||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext}; |
|||
|
|||
// Construct the Verilated model, from Vtop.h generated from Verilating
|
|||
|
|||
Vlng *topp{new Vlng{contextp.get()}}; |
|||
|
|||
/* Return information to caller. */ |
|||
|
|||
pinfo->handle = topp; |
|||
pinfo->step = step; |
|||
|
|||
#define VL_DATA(size, name, msb, lsb) i += msb - lsb + 1; // Count ports
|
|||
|
|||
i = 0; |
|||
#include "inputs.h"
|
|||
pinfo->in_count = i; |
|||
|
|||
pinfo->out_count = outs; |
|||
pinfo->inout_count = inouts; |
|||
pinfo->in_fn = accept_input; |
|||
pinfo->method = After_input; // Verilator requires input to advance.
|
|||
} |
|||
#undef VL_DATA
|
|||
@ -0,0 +1,316 @@ |
|||
*ng_script_with_params |
|||
// This Ngspice interpreter script accepts arbitrary argiments to |
|||
// the Verilator compiler (Verilog to C++) and builds a shared library |
|||
// or DLL that can be loaded by the d_cosim XSPICE code model. |
|||
// Instances of the model are then digital circuit elements whose |
|||
// behaviour is controlled by the Verilog source. |
|||
|
|||
set bad=0 |
|||
if $?argc = 0 |
|||
set bad=1 |
|||
end |
|||
|
|||
if $argc <= 0 |
|||
set bad=1 |
|||
end |
|||
|
|||
if $bad |
|||
echo Arguments acceptable to Verilator are required. |
|||
quit |
|||
end |
|||
|
|||
// Disable special processing of '{'. |
|||
|
|||
set noglob |
|||
|
|||
// Set parameters for Windows or Unix-like OS. |
|||
// For setting CFLAGS (passed to Verilator) it is somewhat arbitrarily |
|||
// assumed that if Ngspice was compiled with VisualC++, then that is |
|||
// the compiler to be used with Verilator. Edit to change. |
|||
|
|||
// Compilation option for C/C++: -fpic is required by GCC for a shared library |
|||
|
|||
if $oscompiled = 8 // VisualC++ - Verilator is a Perl script |
|||
setcs cflags="--CFLAGS -fpic --compiler msvc" |
|||
else |
|||
setcs cflags="--CFLAGS -fpic" // For g++ |
|||
end |
|||
|
|||
if $oscompiled = 2 | $oscompiled = 3 | $oscompiled = 8 // Windows |
|||
set windows=1 |
|||
set dirsep1="\\" |
|||
set dirsep2="/" |
|||
set vloc="C:/mingw64/bin/verilator" // Expected location on Windows |
|||
set run_verilator="perl $vloc" |
|||
else |
|||
set windows=0 |
|||
set dirsep1="/" |
|||
set run_verilator=verilator |
|||
end |
|||
|
|||
if $oscompiled = 7 // MacOS |
|||
set macos=1 |
|||
setcs cflags="$cflags --compiler clang" |
|||
else |
|||
set macos=0 |
|||
end |
|||
|
|||
// Loop through the arguments to find Verilog source: some_path/xxxx.v |
|||
// The output file will have the same base name. |
|||
|
|||
let index=1 |
|||
set off=1 // Avoid error in dowhile |
|||
repeat $argc |
|||
set base="$argv[$&index]" |
|||
let index = index + 1 |
|||
strstr l "$base" "" |
|||
if $l > 2 // Look for xxxx.v |
|||
strslice tail "$base" -2 2 |
|||
strcmp bad "$tail" ".v" |
|||
if $bad <> 0 |
|||
set base="" |
|||
continue |
|||
end |
|||
let l = $l - 2 |
|||
strslice base "$base" 0 $&l |
|||
else |
|||
set base="" |
|||
continue |
|||
end |
|||
|
|||
dowhile $off >= 0 // Strip leading directories |
|||
strstr off "$base" "$dirsep1" |
|||
if $windows |
|||
if $off < 0 |
|||
strstr off "$base" "$dirsep2" |
|||
end |
|||
end |
|||
if $off >= 0 |
|||
let off=$off+1 |
|||
strslice base "$base" $&off $l |
|||
end |
|||
end |
|||
|
|||
strstr l "$base" "" // Check for zero-length string |
|||
if $l > 0 |
|||
break |
|||
end |
|||
end |
|||
|
|||
if index - 1 > $argc |
|||
set base=verilated // Default name |
|||
end |
|||
|
|||
// Define working directory for Verilator |
|||
|
|||
set tail="_obj_dir" |
|||
setcs objdir="$base$tail" |
|||
|
|||
// Default base name of output file. |
|||
|
|||
if $windows |
|||
setcs tail=".DLL" |
|||
else |
|||
setcs tail=".so" |
|||
end |
|||
setcs soname="$base$tail" |
|||
|
|||
// First convert to C++, PREFIX determines the file names. |
|||
|
|||
setcs prefix="Vlng" |
|||
|
|||
// Run Verilator on the given input files. |
|||
|
|||
shell $run_verilator --Mdir $objdir --prefix $prefix $cflags --cc $argv |
|||
|
|||
// Parse the primary interface Class definition for members representing |
|||
// the ports of the top-level Verilog module. |
|||
// Example conversion: VL_IN8(&Clk,0,0); ==> VL_DATA(8,Clk,0,0) |
|||
|
|||
cd $objdir |
|||
echo "/* Generated code: do not edit. */" > inouts.h |
|||
echo "/* Generated code: do not edit. */" > inputs.h |
|||
echo "/* Generated code: do not edit. */" > outputs.h |
|||
|
|||
// This loop is intended to have the same effect as: |
|||
// sed --quiet -e 's/VL_IN\([0-9]*\)(&\(.*\);/VL_DATA(\1,\2/p' \ |
|||
// obj_dir/${PREFIX}.h >> inputs.h |
|||
|
|||
set htail=".h" |
|||
setcs inout="VL_INOUT" |
|||
setcs in="VL_IN" |
|||
setcs out="VL_OUT" |
|||
|
|||
set fn="$prefix$htail" // Like foo-obj_dir/Vlng.h |
|||
fopen fh $fn |
|||
if $fh < 0 |
|||
quit |
|||
end |
|||
|
|||
while 1 |
|||
fread line $fh l |
|||
if $l < 0 |
|||
break |
|||
end |
|||
|
|||
// Does it contain a closing parenthesis? |
|||
|
|||
strstr off "$line" ")" |
|||
if $off < 0 |
|||
continue // No ")", ignore. |
|||
end |
|||
let off = $off + 1 |
|||
strslice line "$line" 0 $&off // Slice off tail. |
|||
|
|||
// Is it an inout port definition? |
|||
|
|||
strstr off "$line" $inout |
|||
if $off >= 0 // Match found |
|||
let off = $off + 8 // strlen("VL_INOUT") == 8 |
|||
strslice line "$line" $&off $l |
|||
strstr off "$line" "(" |
|||
strslice size "$line" 0 $off |
|||
let off = $off + 2 // strlen("(&") == 2 |
|||
strslice line "$line" $&off $l |
|||
echo VL_DATA($size,$line >> inouts.h // New macro invocation |
|||
continue |
|||
end |
|||
|
|||
// Input port? |
|||
|
|||
strstr off "$line" $in |
|||
if $off >= 0 // Match found |
|||
let off = $off + 5 // strlen("VL_IN") == 5 |
|||
strslice line "$line" $&off $l |
|||
strstr off "$line" "(" |
|||
strslice size "$line" 0 $off |
|||
let off = $off + 2 // strlen("(&") == 2 |
|||
strslice line "$line" $&off $l |
|||
echo VL_DATA($size,$line >> inputs.h // New macro invocation |
|||
continue |
|||
end |
|||
|
|||
// Output port? |
|||
|
|||
strstr off "$line" $out |
|||
if $off >= 0 // Match found |
|||
let off = $off + 6 // strlen("VL_OUT") == 6 |
|||
strslice line "$line" $&off $l |
|||
strstr off "$line" "(" |
|||
strslice size "$line" 0 $off |
|||
let off = $off + 2 // strlen("(&") == 2 |
|||
strslice line "$line" $&off $l |
|||
echo VL_DATA($size,$line >> outputs.h // New macro invocation |
|||
continue |
|||
end |
|||
end |
|||
fclose $fh |
|||
cd .. |
|||
|
|||
// The shared library/DLL contains some ngspice source code as |
|||
// well as that created by Verilator. Find it by scanning $sourcepath. |
|||
|
|||
set shimfile=verilator_shim.cpp |
|||
set shimobj=verilator_shim.o |
|||
set mainfile=verilator_main.cpp |
|||
set srcdir=src |
|||
set silent_fileio // Silences fopen complaints |
|||
|
|||
let i=1 |
|||
repeat $#sourcepath |
|||
set stem="$sourcepath[$&i]" |
|||
let i = i + 1 |
|||
set fn="$stem$dirsep1$shimfile" |
|||
fopen fh $fn |
|||
if $fh > 0 |
|||
break |
|||
end |
|||
set stem="$stem$dirsep1$srcdir" |
|||
set fn="$stem$dirsep1$shimfile" |
|||
fopen fh $fn |
|||
if $fh > 0 |
|||
break |
|||
end |
|||
end |
|||
|
|||
if $fh > 0 |
|||
fclose $fh |
|||
set fn_main="$stem$dirsep1$mainfile" |
|||
else |
|||
echo Can not find C++ source file $shimfile |
|||
quit |
|||
end |
|||
|
|||
if $windows |
|||
// Verilator makes a mess of absolute include paths passed by --CFLAGS. |
|||
// Copy the files instead. |
|||
|
|||
set incdir=ngspice |
|||
shell xcopy /i "$stem$dirsep1$incdir" "$objdir$dirsep1$incdir" |
|||
setcs include="--CFLAGS -I." |
|||
|
|||
// Copy verilator_shim.cpp for MSVC.CMD. |
|||
|
|||
shell copy "$fn" "$objdir" |
|||
else |
|||
// Some header files are with the source. |
|||
|
|||
strstr off "$stem" "." |
|||
if $off <> 0 |
|||
setcs include="--CFLAGS -I$stem" |
|||
else |
|||
setcs include="--CFLAGS -I..$dirsep1$stem" // Relative path |
|||
end |
|||
end |
|||
|
|||
|
|||
// Compile the code. Verilator only does that when building an executable, |
|||
// so include verilator_main.cpp. |
|||
|
|||
shell $run_verilator --Mdir $objdir --prefix $prefix $include $cflags |
|||
+ --cc --build --exe |
|||
+ $fn_main $fn $argv |
|||
|
|||
strcmp bad "$shellstatus" "0" |
|||
|
|||
if $bad = 0 |
|||
// g++ must be available: make a shared library/DLL. |
|||
|
|||
set v_objs="$objdir$dirsep1$shimobj $objdir/verilated.o $objdir/verilated_threads.o" |
|||
setcs tail="__ALL.a" |
|||
setcs v_lib="$objdir/$prefix$tail" // Like Vlng__ALL.a |
|||
|
|||
shell g++ --shared $v_objs $v_lib -pthread -lpthread -o $soname |
|||
else |
|||
// Assume we have CL.EXE and use that. A script avoids multiple \escapes. |
|||
|
|||
if $windows = 0 |
|||
quit |
|||
end |
|||
|
|||
// Look for MSVC.CMD |
|||
|
|||
set msvcfile=MSVC.CMD |
|||
let i=1 |
|||
repeat $#sourcepath |
|||
set stem="$sourcepath[$&i]" |
|||
let i = i + 1 |
|||
set fn="$stem$dirsep1$msvcfile" |
|||
fopen fh $fn |
|||
if $fh > 0 |
|||
break |
|||
end |
|||
end |
|||
if $fh > 0 |
|||
fclose $fh |
|||
else |
|||
echo Can not find bulid file $msvcfile |
|||
quit |
|||
end |
|||
|
|||
echo Building with MSVC compiler, CL.EXE. |
|||
cd $objdir |
|||
shell $fn |
|||
cd .. |
|||
end |
|||
quit |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue