Compile petsc included code using a makefile, failed for '.f90' but passed for '.F90' - makefile

I'm leaning petsc (3.13.1) on a Linux virtual machine.
The compiler is mpich-3.2.1 compiled with gfortran.
While going through the tutorials I found the extensinos are .F90,
the files did not work after I changed the ext to .f90.
I added some rules for .f90 in the makefile, still, it did not work.
I'm wondering how to revise makefile for the .f90 extensions.
Test codes:
program test
#include <petsc/finclude/petscsys.h>
use petscsys
type(PetscInt) :: ierr
call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
if (ierr .ne. 0) then
write(*,*) 'Unable to initialize PETSc'
stop
end if
call PetscFinalize(ierr)
end program test
saved as test_f90.f90 and test_F90.F90
the test_f90.f90 did not work
[cfd#localhost tutorial]$ make test_f90
mpif90 -fPIC -Wall -ffree-line-length-0 -Wno-unused-dummy-argument -g -O -I/home/cfd/petsc-3.13.1/linux-gnu/include -I/home/cfd/petsc-3.13.1/include -L/home/cfd/petsc-3.13.1/linux-gnu/lib -Wl,-rpath,/home/cfd/petsc-3.13.1/linux-gnu/lib -o test_f90 test_f90.f90 -lpetsc -lm
Warning: test_f90.f90:3: Illegal preprocessor directive
test_f90.f90:6.14:
type(PetscInt) :: ierr
1
Error: Derived type 'petscint' at (1) is being used before it is defined
make: *** [test_f90] Error 1
while the test_F90.F90 passed
[cfd#localhost tutorial]$ make test_F90
mpif90 -fPIC -Wall -ffree-line-length-0 -Wno-unused-dummy-argument -g -O -I/home/cfd/petsc-3.13.1/linux-gnu/include -I/home/cfd/petsc-3.13.1/include -L/home/cfd/petsc-3.13.1/linux-gnu/lib -Wl,-rpath,/home/cfd/petsc-3.13.1/linux-gnu/lib -o test_F90 test_F90.F90 -lpetsc -lm
The makefile is revised from $PETSC_DIR/share/petsc/Makerfile.user
where the following rules are added
% : %.f90
$(LINK.F) -o $# $^ $(LDLIBS)
%.o: %.f90
$(COMPILE.F) $(OUTPUT_OPTION) $<
the full makefile:
# -*- mode: makefile -*-
PETSc.pc := $(PETSC_DIR)/$(PETSC_ARCH)/lib/pkgconfig/PETSc.pc
PACKAGES := $(PETSc.pc)
CC := $(shell pkg-config --variable=ccompiler $(PACKAGES))
CXX := $(shell pkg-config --variable=cxxcompiler $(PACKAGES))
FC := $(shell pkg-config --variable=fcompiler $(PACKAGES))
CFLAGS_OTHER := $(shell pkg-config --cflags-only-other $(PACKAGES))
CFLAGS := $(shell pkg-config --variable=cflags_extra $(PACKAGES)) $(CFLAGS_OTHER)
CXXFLAGS := $(shell pkg-config --variable=cxxflags_extra $(PACKAGES)) $(CFLAGS_OTHER)
FFLAGS := $(shell pkg-config --variable=fflags_extra $(PACKAGES))
CPPFLAGS := $(shell pkg-config --cflags-only-I $(PACKAGES))
LDFLAGS := $(shell pkg-config --libs-only-L --libs-only-other $(PACKAGES))
LDFLAGS += $(patsubst -L%, $(shell pkg-config --variable=ldflag_rpath $(PACKAGES))%, $(shell pkg-config --libs-only-L $(PACKAGES)))
LDLIBS := $(shell pkg-config --libs-only-l $(PACKAGES)) -lm
print:
#echo CC=$(CC)
#echo CXX=$(CXX)
#echo FC=$(FC)
#echo CFLAGS=$(CFLAGS)
#echo CXXFLAGS=$(CXXFLAGS)
#echo FFLAGS=$(FFLAGS)
#echo CPPFLAGS=$(CPPFLAGS)
#echo LDFLAGS=$(LDFLAGS)
#echo LDLIBS=$(LDLIBS)
% : %.f90
$(LINK.F) -o $# $^ $(LDLIBS)
%.o: %.f90
$(COMPILE.F) $(OUTPUT_OPTION) $<
% : %.F90
$(LINK.F) -o $# $^ $(LDLIBS)
%.o: %.F90
$(COMPILE.F) $(OUTPUT_OPTION) $<
% : %.c
$(LINK.c) -o $# $^ $(LDLIBS)
%.o: %.c
$(COMPILE.cc) $(OUTPUT_OPTION) $<
% : %.cxx
$(LINK.cc) -o $# $^ $(LDLIBS)
%.o: %.cxx
$(COMPILE.cc) $(OUTPUT_OPTION) $<

Thanks for Mark and evets.
I fix it by adding the -cpp flag to FFLAGS
after checking the preprocessing part of
the manual https://linux.die.net/man/1/gfortran
The makefile revised part:
FFLAGS += -cpp
% : %.f90
$(LINK.F) -o $# $^ $(LDLIBS)
%.o: %.f90
$(COMPILE.F) $(FFLAGS) $(OUTPUT_OPTION) $<

Related

makefile error: “make: *** No rule to make target …”

I'm trying to use GCC (linux) with a makefile to compile my project.
I get the following error
"No rule to make target 'output/src/main.o', needed by 'test'. Stop."
This is the makefile:
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix ./output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I ./src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
%.o: %.c
#mkdir -p ./output
$(CC) $(CFLAGS) $(INCLUDES) -o $(addprefix ./output/, $#) -c $<
clean:
rm -rf ./output
This should work. Note the use of mkdir $(#D) to create output directories as needed.
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
output/%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) $(INCLUDES) -o $# -c $<
clean:
rm -rf output
Running it here with make clean test:
rm -rf output
gcc -O2 -Wall -g -I src -o output/src/hello.o -c src/hello.c
gcc output/src/hello.o -lpthread -o test

What does “linker input file unused because linking not done” mean?

This is weird. The compiler throws this warning though everything works as expected.
This is the makefile that throws the warning:
TARGET = $(notdir $(shell pwd))
LIBS = -lm -lev3dev-c
D_BIN = Build-Assets
ifeq ($(OS),Windows_NT)
LIBS := $(LIBS) -lws2_32
D_BIN := $(D_BIN)/mingw
endif
D_H = ../../source/ev3
CFLAGS = $(addprefix -I, $(D_H)) -O2 -std=gnu99 -W -Wall -Wno-comment
ifeq ($(OS),Windows_NT)
CC = gcc
else
CC = arm-linux-gnueabi-gcc
endif
ifeq ($(OS),Windows_NT)
E_BIN = .exe
else
E_BIN =
endif
F_BIN = $(TARGET)$(E_BIN)
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard MotorControl/*.c)))
.PHONY: default all clean
default: $(F_BIN)
all: default
$(OBJECTS): $(D_BIN)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(F_BIN) $(OBJECTS)
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
clean:
-rm -f $(D_BIN)/*.o
-rm -f $(F_BIN)
I should add that I have no idea what I'm doing... I am just starting out with C and those damn makefiles are very overwhelming.
The -c option skips the final link and produces a relocatable object file:
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
This is why linker input files are not used at this stage. You should be able to remove the -c option, and the command will produce an executable as a result.

Makefile objects from .c .cpp and .S sources

I am facing a problem with my makefile. I am trying to compile .c; .cpp and .S files from ./src/. The objects should go into ./obj/ and the binaries into ./bin/. With my current file, it tries to searches for files in ./src/, but tries to compile objectfiles for each extension. So for example, if it finds kernel.cpp, it will try to compile kernel.S and kernel.c, but they are not there, so i get an error.
Here is my code:
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.S=$(OBJDIR)/%.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
I might try to separate SRCS into SRCS_Cpp and so on... But i don't know if that's the best solution. I am pretty new to makefiles^^
I think i found the solution^^
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS_c = $(wildcard $(SRCDIR)/*.c)
SRCS_cpp = $(wildcard $(SRCDIR)/*.cpp)
SRCS_S = $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS_c:$(SRCDIR)/%.c=$(OBJDIR)/%_c.o) $(SRCS_cpp:$(SRCDIR)/%.cpp=$(OBJDIR)/%_cpp.o) $(SRCS_S:$(SRCDIR)/%.S=$(OBJDIR)/%_S.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJDIR)/%_c.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_cpp.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_S.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
Is there something i do wrong? I am trying to compile a kernel without the use of a cross-compiler^^

Not able to include a library in makefile

I am kind of new in the use of make.
I have a library written in C which is in the folder folder1
Where these files are there is also a makefile which is the following:
PREFIX ?= /usr/local
CC = gcc
AR = ar
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
APRILTAG_SRCS := $(shell ls *.c common/*.c)
APRILTAG_HEADERS := $(shell ls *.h common/*.h /usr/include/flycapture/*.h)
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
TARGETS := libapriltag.a libapriltag.so
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
Then, in the folder example I have some example which I can just run by giving the following command in the terminal:
./opencv_demo
or
./apriltag_demo
In this folder example I have another makefile which is the following:
CC = gcc
CXX = g++
CPPFLAGS = -I..
CFLAGS = -std=gnu99 -Wall -Wno-unused-parameter -Wno-unused-function -O4
CXXFLAGS = -Wall -O4
LDFLAGS = -Lusr/include/flycapture -lpthread -lm
INC_DIR = /usr/include/flycapture
TARGETS := apriltag_demo opencv_demo
.PHONY: all
all: apriltag_demo opencv_demo
apriltag_demo: apriltag_demo.o ../libapriltag.a
#echo " [$#]"
#$(CC) -o $# $^ $(LDFLAGS)
opencv_demo: opencv_demo.o ../libapriltag.a /usr/include/flycapture/Error.h
#echo " [$#]"
#$(CXX) -o $# $^ $(LDFLAGS) `pkg-config --libs opencv`
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS) $(CPPFLAGS)
%.o: %.cc
#echo " $#"
#$(CXX) -o $# -c $< $(CXXFLAGS) $(CPPFLAGS)
.PHONY: clean
clean:
#rm -rf *.o $(TARGETS)
If I do make in the folder1 I get the following error:
opencv_demo.o: In function `main':
opencv_demo.cc:(.text.startup+0x24e): undefined reference to `FlyCapture2::Error::Error()'
opencv_demo.cc:(.text.startup+0x2a7): undefined reference to `FlyCapture2::Error::~Error()'
opencv_demo.cc:(.text.startup+0x11a0): undefined reference to `FlyCapture2::Error::~Error()'
collect2: error: ld returned 1 exit status
make[1]: *** [opencv_demo] Error 1
make[1]: Leaving directory `/home/fschiano/Repositories/apriltag2/example'
make: *** [all] Error 2
If I am not wrong this error tells me that I did not include a library.
In the file opencv_demo.cc I did:
#include "flycapture/FlyCapture2.h"
#include "flycapture/Error.h"
using namespace FlyCapture2;
Headers which are in /usr/include/flycapture a folder which contains all the headers needed for what I need in the file opencv_demo.cc.
I don't know why it is not working, someone is able to help me?
I think I should write in the makefile where to search for the libraries but I don't know how.
I tried to write the following things in the makefile separately but they are not working :
LDFLAGS = -Lusr/include/flycapture -lpthread -lm
INC_DIR = /usr/include/flycapture
DEPS = $(INC_DIR)/Error.h

Can not create shared object from object files

I have wrote a makefile to compile a dynamic library. However, output .so file does not contains all of the methods.
I have used this Makefile:
CC=g++
CFLAGS=-fPIC -g
LDFLAGS=-shared
SRCDIR=src
SOURCES=$(shell echo $(SRCDIR)/*.cpp)
HEADERS=$(shell echo $(SRCDIR)/*.h)
OBJECTS=$(SOURCES:.cpp=.o)
LIBDIR=lib
INCDIR=include
LIBRARIES=-lboost_filesystem -lboost_system -lopencv_core -lopencv_highgui -lopencv_imgproc
OUT=$(LIBDIR)/libAgeGender.so
all: $(SOURCES) $(HEADERS) $(OUT)
.cpp.o:
$(CC) $(CFLAGS) $< -o $# $(LDFLAGS)
$(OUT): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(LIBRARIES) -o $# $(LDFLAGS)
clean:
rm -f $(SRCDIR)/*.o *~ $(SRCDIR)/*~ $(OUT)
Then i executed this command to see functions inside of an .o file.
nm SDaisy.o | grep ' T '
00000000000070d6 T _ZN6SDaisy11convolutionERKN2cv3MatESt6vectorIfSaIfEEi
000000000000933e T _ZN6SDaisy12extractDaisyERKN2cv3MatE
0000000000007498 T _ZN6SDaisy14gaussianFilterERKN2cv3MatEff
000000000000854a T _ZN6SDaisy16smoothHistogramsERN2cv3MatE
000000000000c088 T _fini
0000000000005960 T _init
When we look into shared object, we can't see methods.
$ nm libAgeGender.so | grep ' T '
0000000000000578 T _fini
0000000000000438 T _init
How can i make it correctly?
Use the right variables and functions, and let make handle the compilation of .o files.
SRCDIR := src
LIBDIR := lib
INCDIR := include
SRC := $(wildcard $(SRCDIR)/*.cpp)
OBJ := $(SRC:.cpp=.o)
OUT := $(LIBDIR)/libAgeGender.so
CXXFLAGS := -fPIC -g
LDFLAGS := -shared
LDLIBS := -lboost_filesystem -lboost_system \
-lopencv_core -lopencv_highgui -lopencv_imgproc
all: $(OUT)
$(OUT): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#

Resources