C++ makefile not linking - c++

EXENAME = prog1
OBJS = link.o main.o
CXX = clang++
CXXFLAGS = -Wall -Wextra
LD = clang++
all : $(EXENAME)
$(EXENAME) : $(OBJS)
$(LD) $(OBJS) -o $(EXENAME)
main.o : link.h main.cpp
$(CXX) $(CXXFLAGS) main.cpp
link.o : link.h link.cpp
$(CXX) $(CXXFLAGS) link.cpp
clean :
-rm -f *.o $(EXENAME)
This is the make file I got but all the function in link can't be called in main. I tried many different ways doesn't work. This works
prog1: main.cpp link.h link.cpp
clang++ -Wall -Wextra -o prog1 main.cpp link.cpp
But I suppose is not the right way to do this?

It would help if you provided at least some of the errors you got (probably the first few).
Your compiler invocation for building object files is wrong. Without any other flags specified, the compiler will try to take all the input files and create an executable out of them. So this rule:
main.o : link.h main.cpp
$(CXX) $(CXXFLAGS) main.cpp
expands to this compilation line:
clang++ -Wall -Wextra main.cpp
The compiler will attempt to compile and link the main.cpp file (only, because that's all that's listed here) into an executable named a.out (by default).
You need to add the -c option to your compile lines if you want to build an object file rather than link a program:
main.o : link.h main.cpp
$(CXX) $(CXXFLAGS) -c main.cpp
Ditto for building link.o.
Even better would be to simply use make's built-in rules for compiling object files rather than writing your own; in that case your entire makefile could just be:
EXENAME = prog1
OBJS = link.o main.o
CXX = clang++
CXXFLAGS = -Wall -Wextra
all : $(EXENAME)
$(EXENAME) : $(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o $(EXENAME)
main.o : link.h
link.o : link.h
clean :
-rm -f *.o $(EXENAME)

Related

Single Makefile to build both main.c and main.cpp

I would like to make main-c to build main-c from main.c.
And make main-cpp to build main-cpp from main.cpp.
I have, all in the same folder:
main.c:
#include <stdio.h>
int main(int argc, char const *argv[]) {
printf("This ic C\n");
}
main.cpp:
#include <iostream>
int main(int argc, char const *argv[]) {
std::cout << "This is C++" << std::endl;
}
Makefile:
CFLAGS = -std=gnu11
CXXFLAGS = -std=gnu++11
CPPFLAGS = -g -Wall -O3
LDFLAGS =
LDLIBS =
OBJS = main.o
APP-C = main-c
APP-CPP = main-cpp
default:
echo "Check README.txt"
main-c: $(OBJS)
$(CC) $^ $(LDLIBS) -o $#
main-cpp: $(OBJS)
$(CXX) $^ $(LDLIBS) -o $#
clean:
-rm -Rf *.o
distclean: clean
-rm -Rf $(APP-C) $(APP-CPP)
So:
$ make main-c
cc -std=gnu11 -g -Wall -O3 -c -o main.o main.c
cc main.o -o main-c
But (also builds from .c):
$ make main-cpp
cc -std=gnu11 -g -Wall -O3 -c -o main.o main.c
c++ main.o -o main-cpp
I was expecting make main-cpp to use $(CXX) $^ $(LDLIBS) -o $# and build from .cpp. What am I missing?
I was expecting make main-cpp to use $(CXX) $^ $(LDLIBS) -o $# and build from .cpp.
It is. make main-cpp --debug will help you see what is going on.
The problem is you are relying on the default rule for making the main.o needed by both main-cpp and main-c target, but you want a different build when make-cpp target is invoked. In this case you'll need to define different non default rules to build the .o files. It's easiest if you just make make-cpp and main-c depend on a .o with a different name. Since they are different builds they should have different names anyway:
CFLAGS = -std=gnu11
CXXFLAGS = -std=gnu++11
CPPFLAGS = -g -Wall -O3
LDFLAGS =
LDLIBS =
APP-C = main-c
APP-CPP = main-cpp
default:
echo "Check README.txt"
main-c: %:%.o
$(CC) $^ $(LDLIBS) -o $#
main-cpp: %:%.o
$(CXX) $^ $(LDLIBS) -o $#
main-cpp.o: main.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $? -o $#
main-c.o: main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $? -o $#
clean:
-rm -Rf *.o
distclean: clean
-rm -Rf $(APP-C) $(APP-CPP)
Both rules, main-c and main-cpp, require main.o to be created to complete, but you don't have a rule for creating main.o.
You're using make's implicit object file creation which is a built-in rule for creating a '.o' file from a source file. It can use either a '.c' or '.cpp/cc/C' file and will build using the appropriate variables. However, since you have both main.c and main.cpp, it looks like it defaults to using the C version.
You'd probably need to create explicit rules (and probably use different names) for each one.

Makefile warning: linker input file unused because linking not done

I'm trying to write my own makefile for a C++ program.
I'm editing an old makefile for a C program one of my teacher gave m, but I really don't understand why it keeps telling me that linking is not done.
I have 4 classes with their corresponding headers plus the main file.
This is my makefile:
OBJS = main.o Class1.o Class2.o Class3.o Class4.o
HEADERS = Class1.hpp Class2.hpp Class3.hpp Class4.hpp
EXE = main
all: $(EXE)
CXX = g++
CXXFLAGS = -std=c++11 -g -c -Wall
LFLAGS = -Wall -std=c++11 -g
# ---------------------------------------------------------------------
# Rules
# ---------------------------------------------------------------------
RM = rm -rf
.SUFFIXES:
.SUFFIXES: .o .cpp
.cpp.o :
$(CXX) $(CXXFLAGS) -c -o $# $<
$(EXE): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(EXE) $(OBJS)
$(OBJS) : $(HEADERS)
clean:
$(RM) $(OBJS)
$(RM) $(EXE)
again:
make clean
make
And these are the error messages I get when I try to compile:
g++ -std=c++11 -g -c -Wall -o main main.o Class1.o Class2.o Class3.o Class4.o
g++: warning: main.o: linker input file unused because linking not done
g++: warning: Class1.o: linker input file unused because linking not done
g++: warning: Class2.o: linker input file unused because linking not done
g++: warning: Class3.o: linker input file unused because linking not done
g++: warning: Class4.o: linker input file unused because linking not done
I understand that this might be because I'm not linking all the .o files together at the end, but isn't it what this line
$(EXE): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(EXE) $(OBJS)
is supposed to do? Since the -c option is not present.
What am I missing?
Thank you everybody for the help.

Makefile, using mpiCC compiler for main.cpp and g++ for other functions of the src code

I have created a source code in C++ and I want to compile it by using makefiles. The problem is that I want my main functions to compile with mpiCC and the other functions to compile with g++. Is this possible?
What should I change in the following makefile?
Thanks in advance,
Ilias
.PHONY: all clean
CC=mpiCC #g++
CFLAGS=-c -O3
LOCAL_INC_PATH = ../include
SOURCES= main.cpp \
f1.cpp \
f2.cpp
OBJECTS=$(patsubst %.cpp,%.o,$(SOURCES))
LIP = $(LOCAL_INC_PATH)
HEADERS = $(LIP)/func_all.h
all: $(OBJECTS)
$(CC) $^ -o MIE -I$(LOCAL_INC_PATH)
%.o: %.cpp
$(CC) $(CFLAGS) $^ -I$(LOCAL_INC_PATH)
clean:
rm *.$(OBJECTS)
You can put an additional explicit rule for main.cpp:
# ...
CC=g++
# ...
SOURCES= f1.cpp \
f2.cpp
OBJECTS=$(patsubst %.cpp,%.o,$(SOURCES)) main.o
# ...
main.o : main.cpp
mpiCC $(CFLAGS) $^ -I$(LOCAL_INC_PATH)
# ...
It is possible, of course.
CC=g++ # compile everything with g++
main.o : CC=mpiCC # compile main.o with mpiCC
The above uses target-specific variables. When compiling main.o it replaces the value of CC with mpiCC.
Please note, the convention is that CC variable is the C compiler, whereas CXX is the C++ one. Same applies to flags, CFLAGS vs CXXFLAGS.

how do I set compilingflags in a makefile?

I'm used to program in IDEs, but switched to vim and plugins recently. Now I try to write a makefile for a c++ project, but somehow if I run make I always get the error
g++ -c -o *.o createOutput.cpp
In file included from /usr/include/c++/4.8/thread:35:0,
from createOutput.cpp:5:
/usr/include/c++/4.8/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \
^
This is my makefile:
CC = clang++
# compiler flags
CFLAGS = -O3 -Wall -Werror -std=c++11
CFLAGS_SFML = -lsfml-graphics -lsfml-window -lsfml-system
all: program.exe clean
program.exe: *.o
$(CC) -o program.exe *.o $(CFLAGS) $(CFLAGS_SFML)
getInput.o: getInput.cpp
$(CC) -c getInput.cpp $(CFLAGS)
createOutput.o: createOutput.cpp
$(CC) -c createOutput.cpp $(CFLAGS)
main.o: main.cpp
$(CC) -c main.cpp $(CFLAGS)
.PHONY: clean
clean:
rm *.o
#echo clean done
Where is my error? Why is it using g++ instead of clang? And why isn't it using the -std=c++11 parameter? Sorry for the beginner questions, I unfortunately can't find a solution with google.
You want to set CXXFLAGS, that gets picked up automatically by make (and sent to your compiler (eg g++, clang++, etc).
make tried to make target '*.o'.
So, instead of that, you can specify sources list explicitly:
CC = clang++
#compiler flags
CFLAGS = -O3 -Wall -Werror -std=c++11
CFLAGS_SFML = -lsfml-graphics -lsfml-window -lsfml-system
SRCS = getInput.cpp createOutput.cpp main.cpp
OBJS = $(SRCS:.cpp=.o)
all: program.exe
program.exe: $(OBJS)
$(CC) -o program.exe *.o $(CFLAGS) $(CFLAGS_SFML)
getInput.o: getInput.cpp
$(CC) -c getInput.cpp $(CFLAGS)
createOutput.o: createOutput.cpp
$(CC) -c createOutput.cpp $(CFLAGS)
main.o: main.cpp
$(CC) -c main.cpp $(CFLAGS)
.PHONY : clean
clean:
rm *.o
#echo clean done
Note definition of variables OBJS and SRCS.

How do I create a makefile for SDL2/C++ on Windows?

As the title states I'm trying to create a makefile for compiling C++ programs using SDL2 on Windows. I have MinGW installed and working. I'm using Sublime 2 as my environment. Here's what I have so far:
CXX = g++
CXXFLAGS = -std=c++0x -g -O3 -w -Wl,-subsystem,windows
INCLFLAGS = -IC:\Libraries\i686-w64-mingw32\include\SDL2
LDFLAGS = -LC:\Libraries\i686-w64-mingw32\lib -lmingw32 -lSDL2main -lSDL2
OBJECTS = main.o
TARGET = 1_hellosdl
$(TARGET) : $(OBJECTS)
$(CXX) $(INCLFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $(TARGET) $(OBJECTS)
main.o :
clean:
rm -rf $(OBJECTS) $(TARGET)
remake:
clean $(TARGET)
Right now when I compile I get the following error:
g++ -std=c++0x -g -O3 -w -Wl,-subsystems,windows -c -o main.o main.cpp
In file included from main.cpp:1:0:
main.hpp:4:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
So the issue is that g++ can't find the SDL include file when it tries to compile main.cpp. I get that this is because $(INCLFLAGS) isn't being added to the line under main.o :.
Optimally, I'd like to specify INCLFLAGS implicitly similar to CXXFLAGS and LDFLAGS, but based on this it doesn't look like it's possible.
Is there a way to do this using an implicit variable or, failing that, what's the best alternative? Is there anything else I am doing wrong?
I managed to solve this by moving $(INCLFLAGS) into $(CXXFLAGS):
INCLFLAGS = -IC:\Libraries\i686-w64-mingw32\include\SDL2
CXXFLAGS = $(INCLFLAGS) -std=c++0x -g -O3 -w -Wl,-subsystem,windows
Additionally, I had to move $(LDFLAGS) to the end in order for it to link correctly:
$(TARGET) : $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS) $(LDFLAGS)