2016-07-27 2 views
0

Моя программа - программа mpi, которая использует intel MKL. для простой, допустим есть main.f90 a.f90 b.f90, в котором a.f90 содержит модуль, который называется mymod нужны другиеMakefile производит для Fortran 90 вызывает неразрешенный внешний символ

Обычно я скомпилировать его как этот

mpiifort *90 /fast /Qmkl /MD -o main.exe 

Я просто сделать это дважды, потому что в первый раз, будет отсутствовать mymod.mod

Теперь я хочу использовать make-файл, так как хочу уменьшить время перекомпиляции. Я пишу это так

IFORT = /fast 
MKL =/Qmkl 
LDFLAGS = /MD 
main:main.obj b.obj 
    mpiifort $(IFORT) $(MKL) $(LDFLAGS) $< -o [email protected] 
mymod.mod:a.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
main.obj:main.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
b.obj:b.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 

Однако, здесь должно быть что-то не так. Я получил кучу unresolved external symbol. Что не так?

+2

Я не эксперт по make-файлу, но похоже, что ваша главная цель не имеет никакой явной зависимости от 'mymod.mod', поэтому это не будет построено. Я тоже мог бы ошибаться –

ответ

0

Во-первых, кто-то еще, возможно, может написать лучший/более полный ответ (или направить нас к одному), и я бы приветствовал это, но ниже я предоставляю очень простой пример.

Теперь мы можем определить (вероятный) источник ошибок: Если заменить команду компиляции только с touch мы можем изготовить простой пример, демонстрирующий этот вопрос

main:main.obj b.obj 
     touch [email protected] 
mymod.mod:a.f90 
     touch [email protected] 
main.obj:main.f90 
     touch [email protected] 
b.obj:b.f90 
     touch [email protected] 

Если мы тогда построим наш «источник файлы»с

>touch main.f90 b.f90 a.f90 

мы можем попытаться построить наш main исполняемый файл:

>make main 

который будет:

touch main.obj 
touch b.obj 
touch main 

Обратите внимание, как это не создает файл mymod.mod. Это означает, что в вашем случае a.f90 не скомпилируется при построении main и, следовательно, необходимые симболы недоступны (т. Е. При связывании есть функции/подпрограммы и т. Д., Которые не определены, так как a.obj недоступен). Если мы сейчас покажем, что main зависит от mymod.mod, регулируя наш Makefile быть

main:main.obj b.obj mymod.mod 
     touch [email protected] 
mymod.mod:a.f90 
     touch [email protected] 
main.obj:main.f90 
     touch [email protected] 
b.obj:b.f90 
     touch [email protected] 

теперь мы можем попытаться строить main (после первой очистки, делая rm *.obj mymod.mod main), и мы получаем:

>make main 
touch main.obj 
touch b.obj 
touch mymod.mod 
touch main 

Таким образом, мы успешно получили make, чтобы построить цель mymod.mod в составе здания main. Обратите внимание, что на самом деле вы, вероятно, хотите обеспечить, чтобы некоторые цели были созданы для других (например, здесь вы, вероятно, захотите скомпилировать a.f90 до b.f90). Вы можете сделать это с помощью списков зависимостей, которые вы можете захотеть автоматически генерировать (см., Например, this question).

+0

Большое спасибо d_1999. Я выясняю способ, который проще:) – user15964

0

я выяснить способ, который отчасти автоматически, если мы используем Интел FORtran

Intel Fortran предоставляет возможность под названием gen-dep, он будет автоматически анализа и вывода информации зависимость может быть использована для Makefile.Так что, выполнив следующую команду, если появляется сообщение об ошибке из-за отсутствия мод файл, просто запустите его дважды

mpiifort *90 /Qmkl /gen-dep > dependency.txt 

мы получили dependency.txt. Откройте его, мы найдем что-то вроде этого

mpifc.bat for the Intel(R) MPI Library 5.1.2 for Windows* 
Copyright(C) 2007-2015, Intel Corporation. All rights reserved. 

mymod.mod : \ 
    a.f90 

a.obj : \ 
    a.f90 

b.obj : \ 
    b.f90 mymod.mod 

main.obj : \ 
    main.f90 \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi_base.mod \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi_sizeofs.mod \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi_constants.mod \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi.mod \ 
    mymod.mod 

Microsoft (R) Incremental Linker Version 14.00.23026.0 
Copyright (C) Microsoft Corporation. All rights reserved. 

-out:a.exe 
-subsystem:console 
"-libpath:c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mkl\lib\intel64_win" 
"/LIBPATH:c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\lib\release_mt" 
"/LIBPATH:c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\lib" 
impi.lib 
a.obj 
b.obj 
main.obj 

Этот модуль, связанный с mpi, является статическим, поэтому просто удалите его. После несложных манипуляций с текстом (с использованием регулярных выражений будет хороший выбор), чтобы сделать его более ясным и компактным, мы можем получить правильный Makefile, как это (я исправлены некоторые ошибки в моем вопросе пост)

IFORT = /fast 
MKL =/Qmkl 
LDFLAGS = /MD 
a: a.obj b.obj main.obj 
    mpiifort $(IFORT) $(MKL) $(LDFLAGS) $^ -o [email protected] 
mymod.mod : a.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
a.obj : a.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
b.obj : b.f90 mymod.mod 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
main.obj : main.f90 mymod.mod 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
+0

Тем не менее, это делает введение нового файла в проект большой болью. Вот почему я больше не использую 'make' для Fortran. Там гораздо лучшие инструменты для автоматического построения, 'cmake',' scons' и 'waf'. –

+0

@VladimirF Привет, VladimirF. Несколько лет назад я думал, что makefile просто не нужен. Несколько месяцев назад я начал использовать make-файл, потому что удобно настраивать разные рабочие режимы: сборка, очистка и т. Д. Несколько дней назад я устал от перекомпиляции, потому что я интенсивно отслеживаю ошибку, я должен написать лучший make-файл, который определяет зависимости. Может быть, в ближайшем будущем я полностью устану от makefile, как и вы:) Но, кстати, хотите добавить простую иллюстрацию на cmake или другие инструменты fortran для сравнения традиционного метода? Я искал на этом сайте и не нашел хороших ответов на вопрос. – user15964

+0

Было бы не по теме поставить что-нибудь здесь. Есть много вопросов о cmake здесь http://stackoverflow.com/search?q=cmake%2Bfortran, а для scons найти что-то на github https://github.com/LadaF/PoisFFT/blob/master/src/SConstruct (это один мой). Существует также сайт документации для cmake http://stackoverflow.com/documentation/cmake/topics –

Смежные вопросы