function paru_make
%PARU_MAKE compiles the ParU mexFunctions
%
% Example:
%   paru_make
%
% You must type the paru_make command while in the ParU/MATLAB directory.

% Copyright FIXME
% SPDX-License-Identifier: GPL-3.0+

fprintf ('Compiling ParU for MATLAB. You must first compile and install the\n') ;
fprintf ('ParU dynamic library and add its folder into your LD_LIBRARY_PATH.\n') ;

v = version ;

flags = '-O -silent ' ;
is64 = ~isempty (strfind (computer, '64')) ;
if (is64)
    % 64-bit MATLAB
    flags = [flags '-largeArrayDims'] ;
else
    error ('32-bit version not supported') ;
end

libs = '-L../../lib -lparu -lmwlapack -lmwblas' ;
if (~(ispc || ismac))
    % for POSIX timing routine
    libs = [libs ' -lrt'] ;
end

if (ispc)
    obj = 'obj' ;
else
    obj = 'o' ;
end

%-------------------------------------------------------------------------------

include = '-I../../include -I../Include' ;
include = [include ' -I../../SuiteSparse_config '] ;
include = [include ' -I../../AMD/Source  -I../../AMD/Include  '] ;
include = [include ' -I../../CAMD/Source -I../../CAMD/Include '] ;
include = [include ' -I../../COLAMD/Source  -I../../COLAMD/Include  '] ;
include = [include ' -I../../CCOLAMD/Source -I../../CCOLAMD/Include '] ;
include = [include ' -I../../UMFPACK/Source -I../../UMFPACK/Include '] ;
include = [include ' -I../../CHOLMOD/Include '] ;
include = [include ' -I../../CHOLMOD/Check '] ;
include = [include ' -I../../CHOLMOD/Cholesky '] ;
include = [include ' -I../../CHOLMOD/Core '] ;
include = [include ' -I../../CHOLMOD/MATLAB '] ;
include = [include ' -I../../CHOLMOD/MatrixOps '] ;
include = [include ' -I../../CHOLMOD/Partition '] ;
include = [include ' -I../../CHOLMOD '] ;
include = [include ' -I../../CHOLMOD/SuiteSparse_metis/GKlib '] ;
include = [include ' -I../../CHOLMOD/SuiteSparse_metis/libmetis '] ;
include = [include ' -I../../CHOLMOD/SuiteSparse_metis/include '] ;
include = [include ' -I../../CHOLMOD/Supernodal '] ;

% use all of CHOLMOD except for the Modify module
flags = [flags ' -DNMODIFY -DBLAS64' ] ;

if (ispc)
    % MSVC does not define ssize_t
    flags = [flags ' -DNO_SSIZE_T'] ;
end

suitesparse_src = { ...
    '../../SuiteSparse_config/SuiteSparse_config', ...
    '../../AMD/Source/amd_l1', ...
    '../../AMD/Source/amd_l2', ...
    '../../AMD/Source/amd_l_aat', ...
    '../../AMD/Source/amd_l_control', ...
    '../../AMD/Source/amd_l_defaults', ...
    '../../AMD/Source/amd_l_dump', ...
    '../../AMD/Source/amd_l_info', ...
    '../../AMD/Source/amd_l_order', ...
    '../../AMD/Source/amd_l_postorder', ...
    '../../AMD/Source/amd_l_post_tree', ...
    '../../AMD/Source/amd_l_preprocess', ...
    '../../AMD/Source/amd_l_valid', ...
    '../../CAMD/Source/camd_l1', ...
    '../../CAMD/Source/camd_l2', ...
    '../../CAMD/Source/camd_l_aat', ...
    '../../CAMD/Source/camd_l_control', ...
    '../../CAMD/Source/camd_l_defaults', ...
    '../../CAMD/Source/camd_l_dump', ...
    '../../CAMD/Source/camd_l_info', ...
    '../../CAMD/Source/camd_l_order', ...
    '../../CAMD/Source/camd_l_postorder', ...
    '../../CAMD/Source/camd_l_preprocess', ...
    '../../CAMD/Source/camd_l_valid', ...
    '../../COLAMD/Source/colamd_l', ...
    '../../CCOLAMD/Source/ccolamd_l', ...
    '../../CHOLMOD/Check/cholmod_l_check', ...
    '../../CHOLMOD/Check/cholmod_l_read', ...
    '../../CHOLMOD/Check/cholmod_l_write', ...
    '../../CHOLMOD/Cholesky/cholmod_l_amd', ...
    '../../CHOLMOD/Cholesky/cholmod_l_analyze', ...
    '../../CHOLMOD/Cholesky/cholmod_l_colamd', ...
    '../../CHOLMOD/Cholesky/cholmod_l_etree', ...
    '../../CHOLMOD/Cholesky/cholmod_l_factorize', ...
    '../../CHOLMOD/Cholesky/cholmod_l_postorder', ...
    '../../CHOLMOD/Cholesky/cholmod_l_rcond', ...
    '../../CHOLMOD/Cholesky/cholmod_l_resymbol', ...
    '../../CHOLMOD/Cholesky/cholmod_l_rowcolcounts', ...
    '../../CHOLMOD/Cholesky/cholmod_l_rowfac', ...
    '../../CHOLMOD/Cholesky/cholmod_l_solve', ...
    '../../CHOLMOD/Cholesky/cholmod_l_spsolve', ...
    '../../CHOLMOD/Core/cholmod_l_aat', ...
    '../../CHOLMOD/Core/cholmod_l_add', ...
    '../../CHOLMOD/Core/cholmod_l_band', ...
    '../../CHOLMOD/Core/cholmod_l_change_factor', ...
    '../../CHOLMOD/Core/cholmod_l_common', ...
    '../../CHOLMOD/Core/cholmod_l_complex', ...
    '../../CHOLMOD/Core/cholmod_l_copy', ...
    '../../CHOLMOD/Core/cholmod_l_dense', ...
    '../../CHOLMOD/Core/cholmod_l_error', ...
    '../../CHOLMOD/Core/cholmod_l_factor', ...
    '../../CHOLMOD/Core/cholmod_l_memory', ...
    '../../CHOLMOD/Core/cholmod_l_sparse', ...
    '../../CHOLMOD/Core/cholmod_l_transpose', ...
    '../../CHOLMOD/Core/cholmod_l_triplet', ...
    '../../CHOLMOD/Core/cholmod_l_version', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_drop', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_horzcat', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_norm', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_scale', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_sdmult', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_ssmult', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_submatrix', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_symmetry', ...
    '../../CHOLMOD/MatrixOps/cholmod_l_vertcat', ...
    '../../CHOLMOD/Partition/cholmod_l_camd', ...
    '../../CHOLMOD/Partition/cholmod_l_ccolamd', ...
    '../../CHOLMOD/Partition/cholmod_l_csymamd', ...
    '../../CHOLMOD/Partition/cholmod_l_metis', ...
    '../../CHOLMOD/Partition/cholmod_l_nesdis', ...
    '../../CHOLMOD/Partition/cholmod_metis_wrapper', ...
    '../../CHOLMOD/Supernodal/cholmod_l_super_numeric', ...
    '../../CHOLMOD/Supernodal/cholmod_l_super_solve', ...
    '../../CHOLMOD/Supernodal/cholmod_l_super_symbolic', ...
    '../../CHOLMOD/MATLAB/cholmod_matlab', ...
    '../../UMFPACK/Source2/umf_l_analyze', ...
    '../../UMFPACK/Source2/umf_l_apply_order', ...
    '../../UMFPACK/Source2/umf_l_cholmod', ...
    '../../UMFPACK/Source2/umf_l_colamd', ...
    '../../UMFPACK/Source2/umf_l_free', ...
    '../../UMFPACK/Source2/umf_l_fsize', ...
    '../../UMFPACK/Source2/umf_l_is_permutation', ...
    '../../UMFPACK/Source2/umf_l_malloc', ...
    '../../UMFPACK/Source2/umf_l_realloc', ...
    '../../UMFPACK/Source2/umf_l_report_perm', ...
    '../../UMFPACK/Source2/umf_l_singletons', ...
    '../../UMFPACK/Source2/umf_dl_assemble', ...
    '../../UMFPACK/Source2/umf_dl_assemble_fixq', ...
    '../../UMFPACK/Source2/umf_dl_blas3_update', ...
    '../../UMFPACK/Source2/umf_dl_build_tuples', ...
    '../../UMFPACK/Source2/umf_dl_create_element', ...
    '../../UMFPACK/Source2/umf_dl_dump', ...
    '../../UMFPACK/Source2/umf_dl_extend_front', ...
    '../../UMFPACK/Source2/umf_dl_garbage_collection', ...
    '../../UMFPACK/Source2/umf_dl_get_memory', ...
    '../../UMFPACK/Source2/umf_dl_grow_front', ...
    '../../UMFPACK/Source2/umf_dl_init_front', ...
    '../../UMFPACK/Source2/umf_dl_kernel', ...
    '../../UMFPACK/Source2/umf_dl_kernel_init', ...
    '../../UMFPACK/Source2/umf_dl_kernel_wrapup', ...
    '../../UMFPACK/Source2/umf_dl_lhsolve', ...
    '../../UMFPACK/Source2/umf_dl_local_search', ...
    '../../UMFPACK/Source2/umf_dl_lsolve', ...
    '../../UMFPACK/Source2/umf_dl_ltsolve', ...
    '../../UMFPACK/Source2/umf_dl_mem_alloc_element', ...
    '../../UMFPACK/Source2/umf_dl_mem_alloc_head_block', ...
    '../../UMFPACK/Source2/umf_dl_mem_alloc_tail_block', ...
    '../../UMFPACK/Source2/umf_dl_mem_free_tail_block', ...
    '../../UMFPACK/Source2/umf_dl_mem_init_memoryspace', ...
    '../../UMFPACK/Source2/umf_dl_report_vector', ...
    '../../UMFPACK/Source2/umf_dl_row_search', ...
    '../../UMFPACK/Source2/umf_dl_scale', ...
    '../../UMFPACK/Source2/umf_dl_scale_column', ...
    '../../UMFPACK/Source2/umf_dl_set_stats', ...
    '../../UMFPACK/Source2/umf_dl_solve', ...
    '../../UMFPACK/Source2/umf_dl_start_front', ...
    '../../UMFPACK/Source2/umf_dl_store_lu', ...
    '../../UMFPACK/Source2/umf_dl_store_lu_drop', ...
    '../../UMFPACK/Source2/umf_dl_symbolic_usage', ...
    '../../UMFPACK/Source2/umf_dl_transpose', ...
    '../../UMFPACK/Source2/umf_dl_triplet_map_nox', ...
    '../../UMFPACK/Source2/umf_dl_triplet_map_x', ...
    '../../UMFPACK/Source2/umf_dl_triplet_nomap_nox', ...
    '../../UMFPACK/Source2/umf_dl_triplet_nomap_x', ...
    '../../UMFPACK/Source2/umf_dl_tuple_lengths', ...
    '../../UMFPACK/Source2/umf_dl_uhsolve', ...
    '../../UMFPACK/Source2/umf_dl_usolve', ...
    '../../UMFPACK/Source2/umf_dl_utsolve', ...
    '../../UMFPACK/Source2/umf_dl_valid_numeric', ...
    '../../UMFPACK/Source2/umf_dl_valid_symbolic', ...
    '../../UMFPACK/Source2/umfpack_gn_tictoc', ...
    '../../UMFPACK/Source2/umfpack_gn_timer', ...
    '../../UMFPACK/Source2/umfpack_dl_col_to_triplet', ...
    '../../UMFPACK/Source2/umfpack_dl_defaults', ...
    '../../UMFPACK/Source2/umfpack_dl_free_numeric', ...
    '../../UMFPACK/Source2/umfpack_dl_free_symbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_get_determinant', ...
    '../../UMFPACK/Source2/umfpack_dl_get_lunz', ...
    '../../UMFPACK/Source2/umfpack_dl_get_numeric', ...
    '../../UMFPACK/Source2/umfpack_dl_get_symbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_load_numeric', ...
    '../../UMFPACK/Source2/umfpack_dl_load_symbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_numeric', ...
    '../../UMFPACK/Source2/umfpack_dl_qsymbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_report_control', ...
    '../../UMFPACK/Source2/umfpack_dl_report_info', ...
    '../../UMFPACK/Source2/umfpack_dl_report_matrix', ...
    '../../UMFPACK/Source2/umfpack_dl_report_numeric', ...
    '../../UMFPACK/Source2/umfpack_dl_report_perm', ...
    '../../UMFPACK/Source2/umfpack_dl_report_status', ...
    '../../UMFPACK/Source2/umfpack_dl_report_symbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_report_triplet', ...
    '../../UMFPACK/Source2/umfpack_dl_report_vector', ...
    '../../UMFPACK/Source2/umfpack_dl_save_numeric', ...
    '../../UMFPACK/Source2/umfpack_dl_save_symbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_scale', ...
    '../../UMFPACK/Source2/umfpack_dl_solve', ...
    '../../UMFPACK/Source2/umfpack_dl_symbolic', ...
    '../../UMFPACK/Source2/umfpack_dl_transpose', ...
    '../../UMFPACK/Source2/umfpack_dl_triplet_to_col', ...
    '../../UMFPACK/Source2/umfpack_dl_wsolve' } ;

% compile each SuiteSparse file (SuiteSparse_config, AMD, COLAMD,
% CAMD, CCOLAMD, UMFPACK, CHOLMOD):

obj_files = ' ' ;
for k = 1:length (suitesparse_src)
    src = suitesparse_src {k} ;
    s = sprintf ('mex -c %s %s %s.c', flags, include, src) ;
    % fprintf ('%s\n', src) ;
    fprintf ('.') ;
    eval (s) ;
    slash = strfind (src, '/') ;
    slash = slash (end) + 1 ;
    o = src (slash:end) ;
    obj_files = [ obj_files ' ' o '.' obj ] ;
end

% compile the paru mexFunction
fprintf (':') ;
s = sprintf ('mex %s -O %s paru.cpp %s %s', flags, include, obj_files, libs) ;
% fprintf ('%s\n', s) ;
eval (s) ;
fprintf ('\n') ;

