2015-01-21 2 views
1

У меня есть структура проекта, как этотFortran: Makefile с уже скомпилированных модулей

-Project 

--Common 

    ---types.f90 

    ---global.f90 

    ---common_routines.f90 

--Program 1 

    ---program1.f90 

    ---module1.f90 

    ---module2.f90 

    ---etc... 

--Program 2 

--etc... 

Где, Common является папка, которая содержит несколько модулей, которые являются общими для всех программ. Как включить эти модули в мой файл?

Я попытался это:

FC = gfortran 
FCFLAGS = -fbounds-check -O3 
FCFLAGS += -I ../Common 

all: program1 

program1: module1.o module2.o module3.o 

program1.o: module1.o module2.o module3.o 

module2.o: module1.o 

module3.o: module2.o module1.o 

%: %.o 
    $(FC) $(FCFLAGS) -o [email protected] $^ 

%.o: %.f90 
    $(FC) $(FCFLAGS) -c $< 

clean: 
    rm -rf *.o *.mod 

, но я получаю неопределенную ссылочную ошибку общих модулей переменных.

+0

Является ли это «неопределенной ссылкой» во время соединения (вы, похоже, не связываетесь с объектными файлами, соответствующими модулям)? – francescalus

+0

Чтобы быть более точным: вы должны изменить '%:% .o', чтобы включить общие модули. – reinierpost

+0

Как это сделать? Я попробовал 'FCFLAGS + = -I ../ Common types.o global.o common_routines.o', но теперь у меня нет правила для создания целевых типов. Нужно с помощью module1.o.Stop.' – Victor

ответ

1

Я попытался FCFLAGS + = -I ../ Общие types.o global.o common_routines.o

Это не будет работать, потому что -I вариант для препроцессора GNU Fortran в укажите путь, в котором препроцессор должен искать файлы, которые должны быть ВКЛЮЧЕНЫ: до компиляция. Вы не можете использовать его для указания пути, где объект файлов (*.o) будет найден после компиляции компоновщик. Это ничего не значит для компоновщик и не передается в компоновщик.

Для простоты предположим, что объектные файлы необходимо связать для program1 просто program1/program1.o плюс уже существующие common/types.o, common/global.o и common/common_routines.o

Тогда следующий Makefile, размещенный в каталоге program1, будет строить это:

OBJS = program1.o ../common/types.o ../common/global.o ../common/common_routines.o 

.phony: all 

all: program1 

program1: program1.o 
    $(FC) -o [email protected] $(FCFLAGS) $(OBJS) 

clean: 
    rm -f *.o program1 

Просто перечислить все необходимые объектные файлы для линкера, в данном случае с помощью $(OBJS)

Вы, возможно, пожелает принять меры предосторожности, чтобы убедиться, что общие модули в актуальном состоянии, прежде чем строить program1, и теперь вы можете подумать, что вы можете сделать это просто замена:

program1: program1.o 

с:

program1: $(OBJS) 

таким образом побуждая makeперекомпилировать любой из четырех объектных файлов, что находится вне даты относительно соответствующего исходного файла, как предпосылка строительства program1

make, безусловно, стремиться сделать это, но будьте осторожны. Таким образом, это будет перекомпилировать, скажем, ../common/types.o от ../common/types.f90 только его неявного рецепта по умолчанию для изготовления .o из .f90, так как это Makefile является не говоря это делать по-другому. Но это может быть не так, как ../common/types.f90 должен быть скомпилирован, если у вас также есть make-файл в common , который оговаривает, как это сделать в некотором режиме, отличном от стандартного.

В этом случае общие файлы объектов всегда должны быть скомпилированы в файле в файле common. Лучше оставить предпосылки program1 в одиночку, но изменить рецепт:

program1: program1.o 
    $(MAKE) -C ../common 
    $(FC) -o [email protected] $(FCFLAGS) $(OBJS) 

Теперь, в любое время program1 должно быть восстановлено, рецепт будет превентивно запустить make в ../common , прежде чем он связывает четыре объектных файлов. (Это небольшая inelegance, что этот $(MAKE) -C ../common будет вызываться, даже если ему нечего делать: этого можно избежать благодаря более продвинутому использованию make).

Наконец вы можете также найти потребность (если не в этом случае, то в другом), чтобы отличить между флагами, переданных Preprocessing и/или флагами переданного компиляцией и/или флагами, передаваемой связи , Обычно они назначаются отдельным переменным make, например. FPPFLAGS (препроцессор), FCFLAGS (компилятор), LDFLAGS (линкер).

0

GNU syntax to define additional include directory является -Idir не -I dir (дополнительное место)

Также убедитесь, что общие модули уже compiled и включают в себя поиск точек пути к каталогу, в котором вы скомпилированные модули, а не исходные файлы:

Этот путь также используется для поиска файлов .mod, когда ранее скомпилированные модули требуются инструкцией USE.

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