Undefined reference, presume makefile is not using headerfiles - c++

#include <iostream>
#include <string>
#include <fstream>
int main (void)
{
// Nothing here.
}
I am using Makefile to compile.
CXXFLAGS = -std=c++11 -O2 -g -Wall -fmessage-length=0
OBJS = ProgramEntry.o
LIBS =
TARGET = Reading
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
Resulting in undefined reference.
undefined reference to --
I think makefile is not using any header file. May I know how to fix the make file, in case if I add a directory for header files.

It is using the headers, or you'd get a compiler error, not a linkage error.
Change the following line to this:
OBJS = ProgramEntry.o GetNodes.o GetElements.o MeshData.o
Or
OBJS = *.o
To add all objects in the current directory.

You're only linking in one of your object files, so the functions defined in the others don't make it into your program.
Add all your .os to OBJS. That appears to be the point of that variable, after all?

Related

How to compile "not-main" (only .hpp) files with makefile in C++?

I'm developing a parallel project with a Main.cpp and a set of .hpp files. I've found the Makefile below suitable to compile, deploy and execute my project on a Xeon Phi. The problem here is that if I edit only one of the .hpp (so not Main.cpp) then when I execute make compile obviously nothing happens (so I have to execute make clean before). Can you help me to change it so if I edit file.hpp then it will compile it? Thanks!
FF_ROOT = /home/luca/fastflow
BOOST_ROOT = /home/luca/boost_1_59_0
CC = icpc -mmic
CXX = $(CC) -std=c++11 -DNO_DEFAULT_MAPPING
INCLUDES = -I $(BOOST_ROOT) -I $(FF_ROOT)
CXXFLAGS =
LDFLAGS = -pthread
OPTFLAGS = -O3 -finline-functions -DNDEBUG -g -O0
TARGETS = \
Main \
.PHONY: all clean copy exec cleanall
.SUFFIXES: .cpp
%: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) $(OPTFLAGS) -o $# $< $(LDFLAGS)
all: compile
compile: $(TARGETS)
copy:
scp $(TARGETS) mic0:
exec:
ssh mic0 './$(TARGETS) $(ARGS)'
clean:
rm -f $(TARGETS)
cleanall : clean
\rm -f *.o *~
Your Makefile is blatantly not sufficient. At the moment it only contains the commands to translate from one input to the next, but it's missing the crucial ingredient of any build system: Dependencies.
Dependencies are hard to maintain by hand. You could add main: a.hpp b.hpp etc by hand, but that doesn't scale and you forget to update it when you refactor. That's why make is not usually something the user should use directly. make is a bit like assembler: it's the final level at which build rules are expressed, but creating the build rules is best left to a higher-level system (e.g. automake or cmake or any of the other competitors in the field; or even the old makedepend).
As a side note, you really don't want to build the binary directly from source, that defeats almost all points of having a Makefile. You really want to break your project into separately compiled translation units, so that you only rebuild the minimal amount after a change.
OBJS := a.o b.o c.o
main: $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $#
.cc.o:
$(CXX) $(CXXFLAGS) -c $< -o $#
# Dependencies! This is in addition to the implied "foo.o: foo.cc" above.
a.o: a.h b.h tools.h
b.o: b.h tools.h
c.o: c.h b.h weirdstuff.h
Many tutorials explain all this.
Add a rule for the source file where it depends on all (local, not system) header files.
Like
Main.cpp: SomeHeaderFile.hpp SomeOtherHeaderFile.hpp

Error: "Mixed implicit and static pattern rules" in my Makefile

I had a working Makefile for small C++ applications that just had a couple of source code files inside a single folder that was also the output folder. Now I am trying to separate source and object files and ran into a problem. This is how my makefile looks right now, I'll go into detail where the problem occurs below.
CC = gcc
CXX = g++
RM = del
TARGET = plox.exe
CFLAGS = -Wall -ggdb -O3 $(INCLUDE)
CXXFLAGS = -std=c++11 -Wall -ggdb -O3 $(INCLUDE)
LDFLAGS = $(LIB) -lglfw3 -lopengl32 -lglu32 -lgdi32
INCLUDE = -I$(GLFW_INC) -I$(GLAD_INC)
LIB = -L$(GLFW_LIB)
SRC_DIR = src
BUILD_DIR = build
GLFW_DIR = d:/external/glfw-3.1
GLFW_INC = $(GLFW)/include
GLFW_LIB = $(GLFW)/lib64
GLAD = d:/external/glad-c
GLAD_INC = $(GLAD)/include
CXX_SOURCES = $(SRC_DIR)/%.cpp
CXX_OBJS = $(addprefix $(BUILD_DIR)/, $(CXX_SOURCES:.cpp=.o))
OBJS = $(CXX_OBJS) $(BUILD_DIR)/glad.o
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) -o $# $^ $(LDFLAGS)
$(CXX_OBJS): %.o: $(SRC_DIR)%.cpp
$(CXX) $(CXXFLAGS) -c -o $# $<
$(BUILD_DIR)/glad.o: src/glad.c
$(CC) -c $(CFLAGS) -c -o $(BUILD_DIR)/glad.o $(SRC_DIR)/glad.c
.PHONY: clean
clean:
$(RM) $(TARGET) $(OBJS)
The problem is in the line:
$(CXX_OBJS): %.o: $(SRC_DIR)/%.cpp
Before my changes, it looked like this:
$(CXX_OBJS): %.o: %.cpp
A friend helped gave me a template and I never really knew what that line really does. In another thread I learned that this is a static pattern rule so I guess this is where I made the mistake. But writing it down just now, I think the error could be earlier already. I might have made a mistake when defining $(CXX_OBJS). Could it be that the objects in that list are of the form build/src/test.o instead of build/test.o?
But how can I fix the addprefix line to produce the correct output? And where does the error in the title come from; where am I mixing those? I thought it could be about the $(SRC_DIR) in the static pattern rule because I probably misunderstood how it worked, but omitting it doesn't make the error go away. Moreover (assuming CXX_OBJS is working correctly later), if the static pattern rule checks every file in the list $(CXX_OBJS) for a match with %.o, and then has a dependency on the same file with ending .cpp, then that is also not correct because of the build folder prefix.
All in all, I'm very confused about how to handle the folder prefixes correctly and any advice is greatly appreciated!
In a static pattern rule, the words in the first section (the targets) have to be real files. None of them can contain patterns (%). You have:
CXX_SOURCES = $(SRC_DIR)/%.cpp
CXX_OBJS = $(addprefix $(BUILD_DIR)/, $(CXX_SOURCES:.cpp=.o))
$(CXX_OBJS): %.o: $(SRC_DIR)%.cpp
So CXX_OBJS is $(BUILD_DIR)/$(SRC_DIR)/%.o, which contains a pattern, so this is illegal.
I don't really know what you're trying to do with CXX_SOURCES. Maybe you wanted:
CXX_SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
instead?
In addition to MadScientist's correct answer, there was another error in my Makefile introduced by renaming variables: mingw32-make couldn't find the -lglfw3 part because I used $(GLFW) in the definition of GLFW_INC and GLFW_LIB, but didn't define it. I wanted to have $(GLFW_DIR) instead.

C++ Wrapper for C library as shared library

I SOLVED THIS ISSUE BY MYSELF
The problem was the linkage of the library.
I copied the libmywrapper.so(i renamed it) file to /usr/lib and linked with -mywrapper
That's it :-)
Original post:
I'm writing a wrapper library that allows to call C++ functions out of C-code.
Unfortnuately it doesn't link...
wrapper.h:
#ifdef __cplusplus
extern "C"
{
#endif
extern char* (keygen) ();
#ifdef __cplusplus
}
#endif
wrapper.cpp:
#include "wrapper.h"
#include <someincludes>
char* keygen ()
{
urandom u;
Makefile:
TARGET := ./mywrapperlib.so
CXXFLAGS := -fPIC -shared -g -Wall -std=c++0x -I../someincludes -I.
CXX := g++
LIB := -lsomelibs
EXT := cpp
BUILDDIR := build
override BUILDDIR := $(strip $(BUILDDIR))
SOURCES := $(wildcard *.$(EXT))
OBJECTS := $(patsubst %.$(EXT), $(BUILDDIR)/%.o, $(SOURCES))
DEPS := $(patsubst %.$(EXT), $(BUILDDIR)/%.dep, $(SOURCES))
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJECTS) $(DEPS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
ifneq ($(MAKECMDGOALS), clean)
-include $(DEPS)
endif
$(OBJECTS): $(BUILDDIR)/%.o: %.$(EXT) $(BUILDDIR)/%.dep $(BUILDDIR)/.tag
$(CXX) $(CXXFLAGS) -c $< -o $#
$(DEPS): $(BUILDDIR)/%.dep: %.$(EXT) $(BUILDDIR)/.tag
mkdir -p $(dir $(#))
$(CXX) $(CXXFLAGS) -MM $< -MT $# -MT $(<:.$(EXT)=.o) -o $#
%.tag:
mkdir -p $(dir $(#))
touch $#
.PHONY: clean
clean:
$(RM) -r $(BUILDDIR)
A test file that should use the library:
test.c:
#include <wrapper.h>
int main()
{
char* test = keygen();
}
When i try to compile it with
gcc -o test.a -g -Iinclude -Llib/mywrapperlib.so test.c
I get
/tmp/ccB9bEot.o: In function `main':
/some/paths/test.c:7: undefined reference to `keygen'
Im very unexperienced with mixing C & C++ code and writing libraries.
Now im stuck and hope that someone can help me with this problem.
EDIT:
I checked the lib with nm:
nm lib/cryptdbwrapperlib.so | grep keygen
0000000000006935 T keygen
So, i guess that the problem is the linkage...
It's to do with the order of your flags to gcc.
Do this:
gcc -o test.a -g -Iinclude test.c -Llib/mywrapperlib.so
# ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
# first second
GCC reads libraries and objects left-to-right and (basically) ignores any that aren't needed "yet". With my proposed change, test.c goes first so GCC knows that it's going to be looking for a symbol keygen; then, when it finally sees -Llib/mywrapperlib.so it scans it for keygen, finds it, and knows that this library is required.
Change the function's signature in wrapper.cpp to
extern "C" char* keygen ()
Otherwise it will be compiled with a C++ style name, and hence be a different function than the one declared in the header.
I SOLVED THIS ISSUE BY MYSELF
The problem was the linkage of the library. I copied the libmywrapper.so(i renamed it) file to /usr/lib and linked with -mywrapper That's it :-)

g++ errors while compiling object files

I wrote a small makefile which follows the general structure, creating object files and then linking to create an executable. Here is how it looks..
CXX=g++
CXXFLAGS=-Wall -g
INCLUDES= -I ./
LDFLAGS= -L ./
LIBS= -lcryptopp
SRCS= test.cpp
OBJS= $(SRCS:.cpp=.o)
EXEC=test
all: $(EXEC)
$(EXEC): $(OBJS)
$(CXX) $(CXXFLAGS) $(INCLUDES) -o $(EXEC) $(OBJS) $(LDFLAGS) $(LIBS)
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $#
Cryptopp library(cryptopp) is static. Now when I try to run this makefile, when the first command which tries to create object file runs.. its gives me many errors like this..
test.cpp:289: instantiated from here
./include/algparam.h:322: warning: unused variable 'p'
./include/algparam.h: In member function 'void CryptoPP::AlgorithmParametersTemplate<T>::MoveInto(void*) const [with T = unsigned char]':
In the end, it links all fine and the executable works but how can I get rid of those warnings without removing -wall? I don't have much experience with make and makefiles.
That's not an error, it's a warning. (Technically, you can consider warnings as errors that don't prevent the compiler from finishing its job.)
And the way you fix it is to fix your code. This has nothing to do with the makefile. Delete the variable 'p' from line 322 in ./include/algparam.h. (There was a bit of a hint in the warning message from the compiler.)
for this warning, you can just comment variable p in test.cpp or .h file, because you don't use it, or like this
in your code
{
...
#ifdef _DEBUG_
xxx p;
#endif
...
}
and in your makefile, if you want to use p, just add -D_DEBUG_ in your CXXFLAGS

Makefile with macro, does not generate any executable

I wrote a Makefile(code below) for my program which contains hello.h, hello.cpp and main.cpp (this is a trivial testbench for hello.cpp).
However, after I type make in the terminal, it tells me
make: `hello.o' is up to date.
Can someone give any hints? Thank you!
#MACRO
CAT_HOME = $(MGC_HOME)
TARGET = my_tb
#OBJECT1 = hello.o
OBJECTS = hello.o main.o
#OBJECT2 = main.o
DEPENDS = hello.cpp main.cpp hello.h
INCLUDES = -I"$(CAT_HOME)/shared/include"
DEFINES =
CXX = /usr/bin/g++
CXXFLAGS = -g -O3 $(DEFINES) $(INCLUDES)
$(TARGETS) : $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS)
$(OBJECTS) : $(DEPENDS)
#phony target to remove all objects and executables
.PHONY: clean
clean:
rm -f *.o
You define a TARGET variable but later try to use $(TARGETS). Theres an S in difference.
Also, it is inefficient to let every .o file depend on every .cpp file. You might as well just write a linear script that recompiles everything unconditionally. Since you're depending on make's built-in rule for creating a .o from the corresponding .cpp, you don't need to declare that dependency explicitly. So you can remove all of the .cpp files from DEPENDS without losing any relevant dependencies.