Makefile for cross compilation linux - c++

I have been asked to port our product into another application.(our s/w is running on linux virtualbox)
I have got a directory of their interface files and also a example code on trying to configure their software/hardware. I see their interface files under the s/w directory. In the reference code directory, I see a makefile with the reference to their reference code.
Trying to run their reference code makefile. getting error that
make: *** No rule to make target `../ main.o" :(
Btw donot understand why SIMUDIR = -I\..\custom_simcode\ this is done in the makefile ?
Also not much familiar with crosscompiler syntax !
ifndef CROSS_CC_PREFIX
CROSS_CC_PREFIX=$(CROSS_COMPILE)
endif
PROGRAM = customer_sim
CC=$(CROSS_CC_PREFIX)gcc
LD=$(CROSS_CC_PREFIX)ld
RANLIB=$(CROSS_CC_PREFIX)corelib
CFLAGS= -g
all: $(PROGRAM)
## Include path
SIMUDIR = -I\..\custom_simcode\
CUST_INT_INC = -I./../cust_Intf/DecHandler/inc \
-I./../CCPU
LIBDIR = -L./../cust_Intf \
-L./../cust_IntfApi
LIBS = -lpthread -customercif -customerapi
LDFLAGS= $(LIBDIR) $(LIBS)
SOURCE = ./../custom_simcode/main.c \
./../custom_simcode/custcode_primitives_init.c \
./../custom_simcode/custccp_primitives_init.c
CFLAGS += $(SIMUDIR) $(CUST_INT_INC) -DPRINT_IO_CONSOLE -UADAPT_CCPU_CUSTIF
OBJS = $(SOURCE:.c=.o)
$(PROGRAM): $(OBJS)
$(CC) -o $# $(OBJS) $(LDFLAGS)
main.o: $(SIMUDIR)/main.c $(SIMUDIR) $(CUST_INT_INC)
$(CC) -c -o /main.o $(SIMUDIR)/main.c
clean:
-rm -f $(OBJS) $(OBJS) $(PROGRAM)

Your $(OBJS) list dependencies for $(PROGRAMs) with directories included but your rule for main.o doesn't have same path.
It would be better to have a generic rule to compile C files like
%.o: %.c
$(CC) -c -o $# $<
Then simply assign extra dependencies for each file like:
$(OBJS): $(SIMUDIR) $(CUST_INT_INC)

Related

SFML library doesn't link with makefile compilation

I have been trying to link the SFML dlls to my windows C++ project, but I can't get it to work. I always end up with:
fatal error: SFML/System.hpp: No such file or directory
I've tried a bunch of things but nothing changes the issue.
Here is my makefile:
PROGRAM = zero_flip
OBJS = src/main.o src/Math.o src/card.o src/game_board.o src/indicator.o src/ui.o
CXX = g++
CXX_FLAGS = -O0 -g -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable
LIB_DIRS = -L./Resources/libs/
LIBS = -lsfml-system -lsfml-graphics -lsfml-window -lsfml-audio
LNK_FLAGS = $(LIB_DIRS) $(LIBS)
DEPS=$(OBJS:.o=.d)
.PHONY: all clean
all: $(PROGRAM)
-include $(DEPS)
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
$(PROGRAM): $(OBJS)
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $^ -o $#
clean:
rm -f $(OBJS) $(DEPS) $(PROGRAM) && clear
The "./Resources/libs/" directory contains:
openal32.dll
sfml-audio-2.dll
sfml-audio-d-2.dll
sfml-graphics-2.dll
sfml-graphics-d-2.dll
sfml-system-2.dll
sfml-system-d-2.dll
sfml-window-2.dll
sfml-window-d-2.dll
Can anyone get me unstuck please this is driving me mad.
This is wrong:
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
This rule says it will compile a source file into an object file, but the recipe actually builds a complete executable: it will compile the source file like xxx.cpp then link it into a program named xxx.o. You need to invoke just the compiler here, not the linker, so you should not have $(LNK_FLAGS) and you need to add the -c option to tell the compiler to stop after compiling and not link.
Then you need to add an -I option to the compile line telling the compiler where to find the header files needed during compilation... in this case SFML/System.hpp.

C++ Makefile on "complex" tree structure

I have found a lot of related questions, but I was still not able to make my own Makefile.
This makefile is using Mingw64 on Windows, and I want it to run on *nix, currently Debian, but I would like to be able to make it run on Alpine too, as it's used in a Docker container.
The project tree structure is something like :
./
src/
main.cpp
Server.cpp <- use asio and Utils/Split.h
Server.h <- use asio
Utils/
Split.h
lib/
asio/include/ <- asio library (without boost, header only)
Makefile <- That is what I am trying to do right now
Dockerfile
I tried multiple things, here is my latest Makefile (that obviously, does not work) :
NAME := GameServer
CXX := g++
CXXFLAGS := -std=c++2a -DASIO_STANDALONE
SRC_DIR := ./src
LIBS := -I lib/asio-1.18.1/include \
-I lib/rapidjson-1.1.0/include \
-I src
rwildcard = $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
SRCS := $(call rwildcard,$(SRC_DIR),*.cpp)
OBJS := $(SRCS:%.cpp=%.o)
.PHONY: all
all: $(NAME)
$(NAME): $(OBJS)
$(CXX) -o $# $^
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c -o $# $< $(LIBS)
Note: the code (.cpp, .h) is valid, it's coming from an already-running project, but built on Visual Studio (compiled with MSVC).
Here are the two functions done my mingw32-make :
g++ -c -o src/Server.o src/main.cpp -I lib/asio/include -I src
g++ -o Server src/main.o src/Server.o
First line : It should builds the .o from the .cpp and adds the include to asio. I added -I src to add src/Utils, but I guess that's not the way of doing it ?
Second line : It should (link ?) the two .o in a single file : the executable.
The errors I am getting with this makefile are :
src/Server.o:main.cpp:(.text+0x36): multiple definition of 'main', src/main.o:main.cpp:(.text+0x36): first defined here (and this, for every .o)
src/main.o:main.cpp:(.text+0x4b): undefined reference to 'Server::Server()' (and this, for every Server methods main calls, even some from asio)
They appears when the second g++ line starts (g++ -o Server src/main.o src/Server.o)
So here are my questions :
What am I doing wrong ?
Is there a better way of trying to make a development environment on Windows and still be able to copy the project in a Docker container (and then compile it with the gcc image) to build it with the same Makefile ?
Sorry if I forgot to mention some details, I am new with Mingw and its environment.
Thank you
Edit : Corrected version :
NAME := GameServer
CXX := g++
CXXFLAGS := -std=c++1z
SRC_DIR := ./src
LIBS := -lwsock32 -lws2_32 \
-I lib/asio-1.18.1/include \
-I lib/rapidjson-1.1.0/include \
-I src
rwildcard = $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
SRCS := $(call rwildcard,$(SRC_DIR),*.cpp)
OBJS := $(SRCS:%.cpp=%.o)
.PHONY: all
all: $(NAME)
$(NAME): $(OBJS)
$(CXX) -o $# $^ $(LIBS)
$(OBJS): $(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $# $< $(LIBS)
Consider the rule...
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c -o $# $< $(LIBS)
This tells make that all items in $(OBJS) depend on all items in $(SRCS). But the command...
$(CXX) $(CXXFLAGS) -c -o $# $< $(LIBS)
...always compiles the first dependency as identified by $<. It just so happens that in your case $< is src/main.cpp.
Instead you should probably use a pattern rule such as...
$(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $# $< $(LIBS)
You can also limit the scope of that rule to only those targets specified by $(OBJS) with a full static pattern rule...
$(OBJS): $(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $# $< $(LIBS)

Error when executing make

I am trying to create a makefile for my project, but i seem to run into some errors, as I am testing new things. My file structure is as such:
~/main #root project folder
~/main/include #header files (mostly class headers)
~/main/src #source files
~/main/src/obj #object files
Makefile
(Makefile is in the root project folder)
Makefile:
CC=g++
IDIR=include
SDIR=src
ODIR=src/obj
DEPS=$(IDIR)/%.h
OBJS=$(ODIR)/%.o
SRCS=$(SDIR)/%.cpp
CFLAGS=-Wall -std=c++11 -I$(IDIR)
$(OBJS): $(SRCS) $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
all: $(OBJS)
gcc -o run $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(OBJS)
For testing purposes I have a single main.cpp in src folder and a random header file in include folder. The error I am getting when running the simple make command is the following:
make: *** No rule to make target `src/obj/%.o', needed by `all'. Stop.
EDIT : With the help of the guys below i came up with the solution
CC=g++
IDIR=include
SDIR=src
ODIR=src/obj
CFLAGS=-Wall -std=c++11 -I$(IDIR)
_DEPS = yo.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
_SRC = main.cpp
SRC = $(patsubst %,$(SDIR)/%,$(_SRC))
$(ODIR)/%.o: $(SRC) $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
all: $(OBJ)
$(CC) -o run $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJS)
There is a difference in using % in your two cases. When you write:
$(ODIR)/%.o : $(SDIR)/%.cpp $(IDIR)/%.h
that will do pattern substitution, and create a bunch of rules like:
$(ODIR)/foo.o : $(SDIR)/foo.cpp $(SDIR)/foo.h
So it's fine there, although you should use the % explicitly there so it's clear to see what the rule is doing.
But when you use it here:
all : $(ODIR)/%.o
That is literally looking for the target $(ODIR)/%.o for which you don't have a rule. There's no substitution. And you don't have a rule to make that target - hence the error. What you meant to do was have all depend on all the actual objects, for which you'll want to use the wildcard function:
SOURCES = $(wildcard $(SDIR)/*.cpp)
OBJECTS = $(SOURCES:$(SDIR)/%.cpp=$(ODIR)/%.o)
all : $(OBJECTS)
gcc -o run $^ $(CFLAGS)
When you use
OBJS=$(ODIR)/%.o
The %.o part does not expand to anything meaningful. It just remains as the literal value %.o. Same problem exists for DEPS and SRCS as well.
You need to use the wildcard and patsub functions. Instead of
DEPS=$(IDIR)/%.h
OBJS=$(ODIR)/%.o
SRCS=$(SDIR)/%.cpp
use
DEPS=$(wildcard $(IDIR)/*.h)
SRCS=$(wildcard $(SDIR)/*.cpp)
OBJS=$(patsub %.cpp,%.o,$(SRCS))

building program with make and automatic dependencies

I have written a simple C++ program, and for the first time I want to compile and link it using a makefile. As a challenge I want to make a makefile, which lists all dependencies by itself. I am following this tutorial. My program consist of main.cpp, ext1.cpp and ext1.h. Following the tutorial, I have the following makefile
VPATH = src include
CPPFLAGS = -o include
CC = gcc
SOURCES = main.cpp \
ext1.cpp
-include $(subst .c,.d,$(SOURCES))
%.d: %.c
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
When I run this I get the message: make: *** No targets specified and no makefile found. Stop. It is not clear to me what I am missing in my case?
You are trying to do too much at once.
Step 1. Your first makefile should build the executable without attempting automatic dependency detection.
VPATH = include src
CPPFLAGS += -Iinclude
CC = gcc
exec: main.o ext1.o
$(CC) $^ -o $#
%.o: %.cc
$(CC) -c $(CPPFLAGS) $< -o $#
main.o ext1.o: ext1.h
Step 2. Once that works perfectly, you can put the header dependencies in separate files:
makefile:
VPATH = include src
CPPFLAGS += -Iinclude
CC = gcc
exec: main.o ext1.o
$(CC) $^ -o $#
%.o: %.cc
$(CC) -c $(CPPFLAGS) $< -o $#
-include *.d
main.d:
main.o : ext1.h
ext1.d:
ext1.o: ext1.h
Step 3. Once that works perfectly, you can generate the dependency files automatically:
VPATH = include src
CPPFLAGS += -Iinclude
CC = gcc
exec: main.o ext1.o
$(CC) $^ -o $#
%.o: %.cc
$(CC) -c -MMD $(CPPFLAGS) $< -o $#
-include *.d
no make file found ? what name you have given for makefile? make sure its makefile or Makefile if you are just executing command make else you can pass file name to make like this
make -f yourmakefile
and changes suggested by Petr Budnik must work

g++: No such file or directory?

(On Linux, trying to set up SDL) I'm having a time with makefiles, I'm finding them hard to learn. Here is the error I'm getting.
g++: error: game.exe: No such file or directory
make: *** [game.exe] Error 1
Here is my makefile. (Any suggestions on making it better would be great. I've just kind of slapped together whatever I could find to work.)
#Game Make file
TARGET = game.exe
OBJS = App.o\
App_OnInit.o\
App_OnEvent.o\
App_OnLoop.o\
App_OnRender.o \
App_OnCleanup.o\
SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs)
CFLAGS = -Wall -o
LIBS =
LDFLAGS =
$(TARGET): $(OBJS)
g++ $(CFLAGS) $(SDL_CFLAGS) $# $(LDFLAGS) $(OBJS) $(SDL_LDFLAGS) $(LIBS)
%.o: src/%.cpp
g++ -c $(SDL_CFLAGS) $< $(SDL_LDFLAGS)
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJS)
You could either exchange $(CFLAGS) and $(SDL_CFLAGS) in the rule to make $(TARGET) or better remove -o from CFLAGS and put it directly before $#:
...
CFLAGS = -Wall
...
$(TARGET): $(OBJS)
g++ $(CFLAGS) $(SDL_CFLAGS) -o $# $(LDFLAGS) $(OBJS) $(SDL_LDFLAGS) $(LIBS)
-o option should immediately precede the name of the executable file to be produced. In your original Makefile it is part of $(CFLAGS) and is followed by the C flags of the SDL library. Therefore the compiler tries to link in game.exe (the $#) instead of producing an executable file by that name.