1function make (what)
2%MAKE compiles the MATLAB interface to GraphBLAS (for testing only)
3% and dynamically links it with the libraries in ../build/libgraphblas.
4%
5% This MATLAB interface to GraphBLAS is meant for testing and development,
6% not for general use.
7%
8% Usage:
9%
10%   make            % just make what has changed (does not check any changes
11%                   % in -lgraphblas, use 'make all' if recompilation is needed
12%   make all        % make everything from scratch
13%
14% GraphBLAS requires an ANSI C11 compliant compiler.  On the Mac, clang 8.0
15% suffices.  gcc should be version 4.9.3 or later
16
17% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
18% SPDX-License-Identifier: Apache-2.0
19
20here = pwd ;
21if (ispc)
22    here = strrep (here, filesep, '/') ;
23end
24if (isempty (strfind (here, 'GraphBLAS/Test')))
25    % this function should only be done in GraphBLAS/Test
26    error ('make should be used in Test directory only') ;
27end
28
29fprintf ('\nCompiling GraphBLAS tests:\n') ;
30
31need_rename = ~verLessThan ('matlab', '9.10') ;
32
33try
34    spok (sparse (1)) ;
35catch
36    here = pwd ;
37    cd ('spok') ;
38    spok_install ;
39    cd (here) ;
40end
41
42if (nargin < 1)
43    what = '' ;
44end
45
46make_all = (isequal (what, 'all')) ;
47
48flags = '-g -R2018a' ;
49
50try
51    if (strncmp (computer, 'GLNX', 4))
52        % remove -ansi from CFLAGS and replace it with -std=c11
53        cc = mex.getCompilerConfigurations ('C', 'Selected') ;
54        env = cc.Details.SetEnv ;
55        c1 = strfind (env, 'CFLAGS=') ;
56        q = strfind (env, '"') ;
57        q = q (q > c1) ;
58        if (~isempty (c1) && length (q) > 1)
59            c2 = q (2) ;
60            cflags = env (c1:c2) ;  % the CFLAGS="..." string
61            ansi = strfind (cflags, '-ansi') ;
62            if (~isempty (ansi))
63                cflags = [cflags(1:ansi-1) '-std=c11' cflags(ansi+5:end)] ;
64                flags = [flags ' ' cflags] ;
65                fprintf ('compiling with -std=c11 instead of default -ansi\n') ;
66            end
67        end
68    end
69catch
70end
71
72mexfunctions = dir ('GB_mex_*.c') ;
73cfiles = [ dir('GB_mx_*.c') ; ...
74           dir('../Demo/Source/bfs5m.c') ; ...
75           dir('../Demo/Source/drowscale.c') ; ...
76           dir('../Demo/Source/dpagerank.c') ; ...
77           dir('../Demo/Source/dpagerank2.c') ; ...
78           dir('../Demo/Source/ipagerank.c') ; ...
79           dir('../Demo/Source/irowscale.c') ; ...
80           dir('../Demo/Source/isequal.c') ; ...
81           dir('../Demo/Source/mis_check.c') ; ...
82           dir('../Demo/Source/mis_score.c') ; ...
83           dir('../Demo/Source/wathen.c') ; ...
84           dir('../Demo/Source/random_matrix.c') ; ...
85           dir('../Demo/Source/simple_rand.c') ; ...
86           dir('../Demo/Source/prand.c') ; ...
87           dir('../Demo/Source/simple_timer.c') ; ...
88           dir('../Demo/Source/tricount.c') ; ...
89           dir('../Demo/Source/usercomplex.c') ] ;
90
91hfiles = [ dir('*.h') ; dir('Template/*.c') ; dir('../Demo/Include/*.h') ] ;
92inc = '-ITemplate -I../Include -I../Source -I../Source/Template -I../Demo/Include' ;
93
94if (ismac)
95    % Mac (do 'make install' for GraphBLAS first)
96    if (need_rename)
97        libraries = '-L/usr/local/lib -lgraphblas_renamed' ; % -lomp' ;
98    else
99        libraries = '-L/usr/local/lib -lgraphblas' ; % -lomp' ;
100    end
101%   flags = [ flags   ' CFLAGS="$CXXFLAGS -Xpreprocessor -fopenmp" ' ] ;
102%   flags = [ flags ' CXXFLAGS="$CXXFLAGS -Xpreprocessor -fopenmp" ' ] ;
103%   flags = [ flags  ' LDFLAGS="$LDFLAGS  -fopenmp"' ] ;
104elseif (ispc)
105    % Windows
106    if (need_rename)
107        libraries = '-L../GraphBLAS/build/Release -L. -lgraphblas_renamed' ;
108    else
109        libraries = '-L../build/Release -L. -lgraphblas' ;
110    end
111    flags = [ flags ' CFLAGS="$CXXFLAGS -wd\"4244\" -wd\"4146\" -wd\"4217\" -wd\"4286\" -wd\"4018\" -wd\"4996\" -wd\"4047\" -wd\"4554\"" '] ;
112else
113    % Linux
114    if (need_rename)
115        libraries = '-L../GraphBLAS/build -L. -lgraphblas_renamed' ;
116    else
117        libraries = '-L../build -L. -lgraphblas' ;
118    end
119    flags = [ flags   ' CFLAGS="$CXXFLAGS -fopenmp -fPIC -Wno-pragmas" '] ;
120    flags = [ flags ' CXXFLAGS="$CXXFLAGS -fopenmp -fPIC -Wno-pragmas" '] ;
121    flags = [ flags  ' LDFLAGS="$LDFLAGS  -fopenmp -fPIC" '] ;
122end
123
124if (need_rename)
125    fprintf ('Linking with -lgraphblas_renamed\n') ;
126    flags = [flags ' -DGBRENAME=1 ' ] ;
127    inc = [inc ' -I../GraphBLAS/rename ' ] ;
128    libgraphblas = '-lgraphblas_renamed' ;
129else
130    libgraphblas = '-lgraphblas' ;
131end
132
133%-------------------------------------------------------------------------------
134
135dryrun = false ;
136
137% Find the last modification time of any hfile.
138% These are #include'd into source files.
139htime = 0 ;
140for k = 1:length (hfiles)
141    t = datenum (hfiles (k).date) ;
142    htime = max (htime, t) ;
143end
144
145if (ispc)
146    obj_extension = '.obj' ;
147else
148    obj_extension = '.o' ;
149end
150
151% compile any source files that need compiling
152any_c_compiled = false ;
153objlist = '' ;
154for k = 1:length (cfiles)
155
156    % get the full cfile filename and  modification time
157    cfile = [(cfiles (k).folder) filesep (cfiles (k).name)] ;
158    tc = datenum (cfiles(k).date) ;
159
160    % get the object file name
161    ofile = cfiles(k).name ;
162    objfile = [ ofile(1:end-2) obj_extension ] ;
163
164    % get the object file modification time
165    ofiles {k} = objfile ;
166    objlist = [ objlist ' ' objfile ] ;
167    dobj = dir (objfile) ;
168    if (isempty (dobj))
169        % there is no object file; the cfile must be compiled
170        tobj = 0 ;
171    else
172        tobj = datenum (dobj.date) ;
173    end
174
175    % compile the cfile if it is newer than its object file, or any hfile
176    if (make_all || tc > tobj || htime > tobj)
177        % compile the cfile
178        fprintf ('.') ;
179        % fprintf ('%s\n', cfile) ;
180        mexcmd = sprintf ('mex -c %s -silent %s %s', flags, inc, cfile) ;
181        if (dryrun)
182            fprintf ('%s\n', mexcmd) ;
183        else
184            % fprintf ('%s\n', mexcmd) ;
185            eval (mexcmd) ;
186        end
187        any_c_compiled = true ;
188    end
189end
190
191% compile the mexFunctions
192for k = 1:length (mexfunctions)
193
194    % get the mexFunction filename and modification time
195    mexfunc = mexfunctions (k).name ;
196    mexfunction = [(mexfunctions (k).folder) filesep mexfunc] ;
197    tc = datenum (mexfunctions(k).date) ;
198
199    % get the compiled mexFunction modification time
200    mexfunction_compiled = [ mexfunc(1:end-2) '.' mexext ] ;
201    dobj = dir (mexfunction_compiled) ;
202    if (isempty (dobj))
203        % there is no compiled mexFunction; it must be compiled
204        tobj = 0 ;
205    else
206        tobj = datenum (dobj.date) ;
207    end
208
209    % compile if it is newer than its object file, or if any cfile was compiled
210    if (make_all || tc > tobj || any_c_compiled)
211        % compile the mexFunction
212        mexcmd = sprintf ('mex -silent %s %s %s %s %s', ...
213            flags, inc, mexfunction, objlist, libraries) ;
214        fprintf (':') ;
215        % fprintf ('%s\n', mexfunction) ;
216        if (dryrun)
217            fprintf ('%s\n', mexcmd) ;
218        else
219            % fprintf ('%s\n', mexcmd) ;
220            eval (mexcmd) ;
221        end
222    end
223end
224
225% compile GB_spones_mex
226mex -g -R2018a GB_spones_mex.c
227
228% load the library
229if (ispc)
230    cd ../build/Release
231    GrB (1)
232    cd ../../Test
233    pwd
234end
235
236