Build dll for large C project with makefile

349 views Asked by At

I'm trying to build simple dll which uses library UMFPACK.

Here is my file "umfsolver.c":

#include <stdio.h>
#include <stdlib.h>
#include "umfpack.h"
#include "amd.h"

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

typedef struct problem_struct
{
    double Control [UMFPACK_CONTROL];
    double Info [UMFPACK_INFO];
    int *Ti;
    int *Tj;
    double *Tx;
    int nrow;
    int ncol;
    int nz;
} problem;


EXPORT problem* __stdcall create(int nrows, int ncols, int nnonzero) 
{

    problem *prob;
    prob = (problem*) malloc(sizeof (problem)) ;
    if (!prob) return (NULL);
    prob->nrow = nrows;
    prob->ncol = ncols;
    prob->nz = nnonzero;
    printf("Creating...\n");
    umfpack_di_defaults (prob->Control) ;
    prob->Control [UMFPACK_PRL] = 3 ;
    prob->Control [UMFPACK_BLOCK_SIZE] = 32 ;
    prob->Ti = (int *) malloc (nnonzero * sizeof (int)) ;
    prob->Tj = (int *) malloc (nnonzero * sizeof (int)) ;
    prob->Tx = (double *) malloc (nnonzero * sizeof (double)) ;
    if (!prob->Ti || !prob->Tj || !prob->Tx ) return (NULL);
    return prob;
}

And here is my makefile:

all: libs umfsolver

include ../../SuiteSparse_config/SuiteSparse_config.mk

#-------------------------------------------------------------------------------
# the optional Partition module requires METIS, CAMD, and CCOLAMD
I_WITH_PARTITION = 
LIB_WITH_PARTITION =
CONFIG1 = -DNCHOLMOD
CONFIG2 = -DNPARTITION
ifeq (,$(findstring -DNCHOLMOD, $(UMFPACK_CONFIG)))
    # CHOLMOD is requested.  See if it is available
    ifeq (../../CHOLMOD, $(wildcard ../../CHOLMOD))
        ifeq (../../COLAMD, $(wildcard ../../COLAMD))
            # CHOLMOD and COLAMD are available
            CONFIG1 =
            LIB_WITH_CHOLMOD = ../../CHOLMOD/Lib/libcholmod.a \
                ../../COLAMD/Lib/libcolamd.a
            # check if METIS is requested and available
            ifeq (,$(findstring -DNPARTITION, $(CHOLMOD_CONFIG)))
                # METIS is requested.  See if it is available
                ifeq ($(METIS_PATH), $(wildcard $(METIS_PATH)))
                    ifeq (../../CAMD, $(wildcard ../../CAMD))
                        ifeq (../../CCOLAMD, $(wildcard ../../CCOLAMD))
                            # METIS, CAMD, and CCOLAMD are available
                            LIB_WITH_PARTITION = $(METIS) \
                                ../../CCOLAMD/Lib/libccolamd.a \
                                ../../CAMD/Lib/libcamd.a
                            I_WITH_PARTITION = -I$(METIS_PATH)/Lib \
                                -I../../CCOLAMD/Include -I../../CAMD/Include
                            CONFIG2 =
                        endif
                    endif
                endif
            endif
        endif
    endif
endif
#-------------------------------------------------------------------------------

C = $(CC) $(CF) $(UMFPACK_CONFIG) $(CONFIG1) $(CONFIG2) \
    -I../Include -I../../AMD/Include -I../../SuiteSparse_config

INC = ../Include/umfpack.h ../../AMD/Include/amd.h ../../SuiteSparse_config/SuiteSparse_config.h

LIBS = $(LAPACK) $(BLAS) $(XERBLA) $(LIB) $(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION) $(CUBLAS_LIB) $(CUDART_LIB)

../Lib/libumfpack.a:
    ( cd ../Lib ; $(MAKE) )

../../AMD/Lib/libamd.a:
    ( cd ../../AMD ; $(MAKE) library )

../../SuiteSparse_config/libsuitesparseconfig.a:
    ( cd ../../SuiteSparse_config ; $(MAKE) library )

../../CHOLMOD/Lib/libcholmod.a:
    - ( cd ../../CHOLMOD && $(MAKE) library )

../../COLAMD/Lib/libcolamd.a:
    - ( cd ../../COLAMD && $(MAKE) library )


../../CCOLAMD/Lib/libccolamd.a:
    - ( cd ../../CCOLAMD && $(MAKE) library )

../../CAMD/Lib/libcamd.a:
    - ( cd ../../CAMD && $(MAKE) library )

$(METIS):
    ( cd $(METIS_PATH) && $(MAKE) )

UMFPACK = ../Lib/libumfpack.a ../../AMD/Lib/libamd.a \
    ../../SuiteSparse_config/libsuitesparseconfig.a \
    $(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION) 

libs: $(UMFPACK)


umfsolver: umfsolver.c $(UMFPACK)
    $(C) -c -DBUILD_DLL umfsolver.c 
    $(C) -shared -o umfsolver.dll umfsolver.o -Wl,--add-stdcall-alias $(UMFPACK) $(LIBS) -lm

I used variables:

CF = -O3 -fexceptions -fPIC
CC = cc
LIB = -lm -lrt
UMFPACK_CONFIG = -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt
MAKE = make
CUBLAS_LIB = 
CUDART_LIB = 
XERBLA = 
BLAS = 
LAPACK = 
METIS_PATH = ../../metis-4.0
METIS = ../../metis-4.0/libmetis.a

It builds with no errors. When I'm calling function create from another program (using static dllimport), it works until some library function need to be called inside create.

It seems like the program goes to infinite loop when either it calls printf("Creating...\n") or umfpack_di_defaults (prob->Control).

When I type make, I get this:

cc    -O3 -fexceptions -fPIC -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt   -I../Include -I../../AMD/Include -I../../SuiteSparse_config -c -DBUILD_DLL umfsolver.c
cc1: warning: fPIC ignored for target (all code is position independent)
cc    -O3 -fexceptions -fPIC -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt   -I../Include -I../../AMD/Include -I../../SuiteSparse_config -shared -o umfsolver.dll umfsolver.o ../Lib/libumfpack.a ../../AMD/Lib/libamd.a ../../SuiteSparse_config/libsuitesparseconfig.a ../../CHOLMOD/Lib/libcholmod.a ../../COLAMD/Lib/libcolamd.a ../../metis-4.0/libmetis.a ../../CCOLAMD/Lib/libccolamd.a ../../CAMD/Lib/libcamd.a     -lm -lrt ../../CHOLMOD/Lib/libcholmod.a ../../COLAMD/Lib/libcolamd.a ../../metis-4.0/libmetis.a ../../CCOLAMD/Lib/libccolamd.a ../../CAMD/Lib/libcamd.a    -Wl,--add-stdcall-alias

I guess that I should somehow change the makefile to put all library files together? How can I do this? Can anyone explain me this?

Thanks!

0

There are 0 answers