使用makefile为大型C项目构建dll

时间:2015-06-24 12:30:01

标签: c dll makefile dllexport umfpack

我正在尝试构建使用库UMFPACK的简单dll。

这是我的文件" 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;
}

这是我的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

我使用了变量:

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

它构建没有错误。当我从另一个程序(使用静态dllimport)调用函数create时,它会起作用,直到需要在create内调用某个库函数。

当程序调用{​​{1}}或printf("Creating...\n")时,程序似乎会进入无限循环。

当我输入make时,我明白了:

umfpack_di_defaults (prob->Control)

我想我应该以某种方式更改makefile以将所有库文件放在一起? 我怎样才能做到这一点?谁能解释一下这个?

谢谢!

0 个答案:

没有答案