Я не слишком хорошо знаком с Make-файлами, поэтому я бы просто перечислил метод «взлома». Мы рассмотрим метод «взлома» в этом тексте позже. У меня есть Makefile и пример исходного кода ex1.cpp, который использует несколько массивов PETSc, векторов, функций вместе с моим собственным регулярным массивом C/C++, который выполняет обмен данными с массивом и векторами PETSc. Это можно рассматривать как миниатюрную версию вашего дела.
Мой Makefile -
PETSC_DIR=/usr/local/petsc
include ${PETSC_DIR}/conf/variables
include ${PETSC_DIR}/conf/rules
include ${PETSC_DIR}/conf/test
CLINKER=g++
ex1 : ex1.o chkopts
${CLINKER} -w -o ex1 ex1.o ${PETSC_LIB}
${RM} ex1.o
./ex1
Конечно вам нужно редактировать PETSC_DIR в папку, PETSc в вашей системе. Ввод «make ex1» будет компилировать и связывать исходный код для создания исполняемого файла и его выполнения.
После я «сделать EX1» на моей системе, два процесса выхода компиляции и компоновки показаны, которые перечислены здесь следующим образом:
Компиляция -
/usr/local/petsc/arch-linux2-c-debug/bin/mpicc -o ex1.o -c -fPIC -Wall -Wwrite-strings -Wno-strict-aliasing -Wno-unknown-pragmas -g3 -fno-inline -O0 -I/usr/local/petsc/include -I/usr/local/petsc/arch-linux2-c-debug/include ex1.cpp
Linking -
g++ -w -o ex1 ex1.o -Wl,-rpath,/usr/local/petsc/arch-linux2-c-debug/lib -L/usr/local/petsc/arch-linux2-c-debug/lib -lpetsc -Wl,-rpath,/usr/local/petsc/arch-linux2-c-debug/lib -lflapack -lfblas -lX11 -lpthread -lm -Wl,-rpath,/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -Wl,-rpath,/usr/lib/x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,/lib/x86_64-linux-gnu -L/lib/x86_64-linux-gnu -lmpichf90 -lgfortran -lm -lgfortran -lm -lquadmath -lm -lmpichcxx -lstdc++ -ldl -lmpich -lopa -lmpl -lrt -lpthread -lgcc_s –ldl
Таким образом, «хитрость» заключается в том, что вы запускаете Makefile и разделяете выходы процесса компиляции и компоновки с этим случаем PETSc. Вы делаете то же самое с исходным исходным кодом, который не содержит PETSc и записывает компиляцию и связывает результаты процесса с ним.
Давайте предположим, что с PETSc-бесплатной версии, выход процесса компиляции г ++ -o ex1.o -I/random_path ex1.cpp и связь результата процесса является г ++ -w -o EX1 ex1.o -llib1 - L/random_lib2.
Следующий шаг - объединить пути компиляции для кода PETSc и кода без PETSc и того же со ссылкой. Таким образом, модифицированная компиляция и связывающие процессы будут:
Модифицированный Компиляция -
/usr/local/petsc/arch-linux2-c-debug/bin/mpicc -o ex1.o -c -fPIC -Wall -Wwrite-strings -Wno-strict-aliasing -Wno-unknown-pragmas -g3 -fno-inline -O0 -I/usr/local/petsc/include -I/usr/local/petsc/arch-linux2-c-debug/include –I/random_path ex1.cpp
Модифицированный Linking -
g++ -w -o ex1 ex1.o -Wl,-rpath,/usr/local/petsc/arch-linux2-c-debug/lib -L/usr/local/petsc/arch-linux2-c-debug/lib -lpetsc -Wl,-rpath,/usr/local/petsc/arch-linux2-c-debug/lib -lflapack -lfblas -lX11 -lpthread -lm -Wl,-rpath,/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -Wl,-rpath,/usr/lib/x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,/lib/x86_64-linux-gnu -L/lib/x86_64-linux-gnu -lmpichf90 -lgfortran -lm -lgfortran -lm -lquadmath -lm -lmpichcxx -lstdc++ -ldl -lmpich -lopa -lmpl -lrt -lpthread -lgcc_s –ldl –llib1 –L/random_lib2
Вы можете ввести измененные команды непосредственно на терминал или сделать BASH чтобы запустить их.
Пример кода PETSc, который вычисляет обратные числа в массиве приведена ниже для справки:
// EX1.CPP
#include <petscvec.h>
#include <petscmat.h>
#include <petscksp.h>
Vec Arr2Vec(double *arr2, int SIZE);
// MAIN FUNCTION
int main(int argc,char **argv)
{
// Initialize PetSc
PetscInitialize(&argc,&argv,(char*)0,"Testing a program!");
// Initialize parameters
int SIZE = 3;
PetscErrorCode ierr;
// **** Create a regular arary and set it with random numbers
double * arr2;
arr2 = new double [SIZE];
arr2[0] = 0.1;
arr2[1] = 0.4;
arr2[2] = 0.2;
// Convert regular arary to PETSc vector [Note that this must do the same effect as the two-step process of conversion from regular array to PETSc arary and that to PETSc vector as listed above]
Vec x = Arr2Vec(arr2, SIZE);
printf("Reciprocal Vector : \n"); VecReciprocal(x);
VecView(x,PETSC_VIEWER_STDOUT_WORLD);
//Cleanup
ierr = VecDestroy(&x);
CHKERRQ(ierr);
PetscFinalize();
return 0;
}
Vec Arr2Vec(double *arr2, int SIZE)
{
PetscScalar *array1;
PetscMalloc(SIZE*sizeof(PetscScalar),&array1);
for(int i=0;i<SIZE;i++)
array1[i]=arr2[i];
// Setup vector
Vec x;
VecCreate(PETSC_COMM_WORLD,&x);
VecSetSizes(x,PETSC_DECIDE,SIZE);
VecSetFromOptions(x);
// Place PetSc array as Vector
VecPlaceArray(x,array1);
return x;
}
Вы хотите, чтобы ваша сборка создавала PETSc, а также создавала код или вы хотите, чтобы ваш код использовал уже построенный PETSc? –
Да, я хочу, чтобы моя сборка построила PETSc, а также построила код – Nazi
Возможно, но это немного сложно. Систему makefile PETSc трудно понять. – Dan