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
Related
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
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) $<
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.
My project is organized like this :
src/plateau.c plateau.h tuile.c tuile.h main.c
tests/tests.c
obj/
bin/
I'm trying to do a makefile with 2 executables. I can't figure out why it doesn't works.
The makefile with one executable only works fine, it looks like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
And with two executables, I tried like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu tests
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
tests: $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o tests
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
$(OBJDIR)/test_honshu.o: $(SRCDIR)/test_honshu.c
$(CC) -c -I src $(SRCDIR)/test_honshu.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
But I have the following message "no rules to make "src/test_honshu.c", necessary for "obj.test_honshu.o", do you have an idea ? Thanks !
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^^