I am trying to compile the below test program:
#include <GL/glfw.h>
int main(int argc, char** argv) {
if(!glfwInit()) {
return -1;
}
if(!glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)) {
return -1;
}
while(glfwGetWindowParam(GLFW_OPENED)) {
glfwSwapBuffers();
}
return 0;
}
but I always get undefined reference errors in regards to the GLFW functions.
Below is my makefile:
CXX = clang++
CXXFLAGS = -Wall -std=c++0x
LDFLAGS = -lglfw
OBJ_DIR = bin
LIB_DIR = -L/usr/lib
INC_DIR = -I/usr/include
SOURCE = main.cpp
OBJECTS = ${SOURCE:%.cpp=$(OBJ_DIR)/%.o}
EXECUTABLE = hello
all: init $(OBJECTS) $(EXECUTABLE)
$(EXECUTABLE):
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) -o $# $(OBJECTS)
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(INC_DIR) -c $< -o $#
init:
#mkdir -p "$(OBJ_DIR)"
clean:
#rm -rf $(OBJ_DIR) $(EXECUTABLE)
I definitely have glfw.h and libglfw.a/.so as when I run locate glfw I get:
:~$ locate glfw
/usr/include/GL/glfw.h
/usr/lib/libglfw.a
/usr/lib/libglfw.so
/usr/lib/libglfw.so.2
/usr/lib/libglfw.so.2.6
The output of nm /usr/lib/libglfw.a | grep glfwInit:
:~$ nm /usr/lib/libglfw.a | grep glfwInit
U _glfwInitialized
U _glfwInitialized
U _glfwInitialized
U _glfwInitialized
0000000000000000 B _glfwInitialized
0000000000000000 T glfwInit
U _glfwInitialized
U _glfwInitialized
U _glfwInitialized
U _glfwInitialized
U _glfwInitialized
U _glfwInitJoysticks
U _glfwInitTimer
00000000000000c0 T _glfwInitJoysticks
0000000000000000 T _glfwInitTimer
and the verbose message from clang:
clang++ -I/usr/include -c main.cpp -o bin/main.o
clang++ -Wall -std=c++0x -Wl --verbose -lglfw -lGL -lGLU -L/usr/lib -o hello bin/main.o
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
clang: warning: argument unused during compilation: '-std=c++0x'
"/usr/bin/ld" -z relro --hash-style=gnu --as-needed --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/usr/lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. -L/lib/x86_64-linux-gnu -L/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib -lglfw -lGL -lGLU bin/main.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o
bin/main.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `glfwInit'
main.cpp:(.text+0x76): undefined reference to `glfwOpenWindow'
main.cpp:(.text+0x97): undefined reference to `glfwGetWindowParam'
main.cpp:(.text+0xa7): undefined reference to `glfwSwapBuffers'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [hello] Error 1
It seems to not be finding the library?
The problem is that the glfw libraries are being specified to the linker before the object file that depends on them. ld searches libraries to resolve dependencies only for the dependencies that it knows about at the point in list of files it's processing. So when ld is searching libglfw.a it doesn't know about the glfwInit dependency in main.o yet. ld (by default) doesn't go back an search the library again.
Try:
$(EXECUTABLE):
$(CXX) $(CXXFLAGS) $(LIB_DIR) -o $# $(OBJECTS) $(LDFLAGS)
Also the libraries should probably be specified in a LDLIBS (or LIBS) variable - LDFLAGS is conventionally use for linker options:
CXX = clang++
CXXFLAGS = -Wall -std=c++0x
LDLIBS = -lglfw -lGL -lGLU
OBJ_DIR = bin
LIB_DIR = -L/usr/lib
INC_DIR = -I/usr/include
SOURCE = main.cpp
OBJECTS = ${SOURCE:%.cpp=$(OBJ_DIR)/%.o}
EXECUTABLE = hello
all: init $(OBJECTS) $(EXECUTABLE)
$(EXECUTABLE):
$(CXX) $(LDFLAGS) $(LIB_DIR) -o $# $(OBJECTS) $(LDLIBS)
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(INC_DIR) -c $< -o $#
init:
#mkdir -p "$(OBJ_DIR)"
clean:
#rm -rf $(OBJ_DIR) $(EXECUTABLE)
Related
I'm trying to run an MPI program that uses pthreads. I am able to compile and run in my local machine but couldn't do that on a server.
This is the command I used to compile.
target1: TARGET=main
target2: TARGET=kmer_finaliser
CC = mpic++
# CPPFLAGS = -pg
# CPPFLAGS = -lm -g -Wall -pthread
CPPFLAGS = -std=c++11 -pthread
USER_LIBS = -I /home/ruchin/sparsehash-sparsehash-2.0.4/src
main: main.o extractor.o com.o kmer_dump.o thread_pool.o
$(CC) $(CPPFLAGS) -o kmer_counter.out main.o extractor.o com.o kmer_dump.o thread_pool.o $(USER_LIBS)
main.o: main.cpp extractor.h com.h kmer_dump.h thread_pool.h
$(CC) $(CPPFLAGS) -c main.cpp $(USER_LIBS)
kmer_finaliser: kmer_finaliser.o kmer_dump.o
$(CC) $(CPPFLAGS) -o kmer_finaliser.out kmer_finaliser.o kmer_dump.o $(USER_LIBS)
kmer_finaliser.o: kmer_finaliser.cpp kmer_dump.h
$(CC) $(CPPFLAGS) -c kmer_finaliser.cpp $(USER_LIBS)
extractor.o: extractor.cpp extractor.h
$(CC) $(CPPFLAGS) -c extractor.cpp $(USER_LIBS)
com.o: com.cpp com.h
$(CC) $(CPPFLAGS) -c com.cpp $(USER_LIBS)
kmer_dump.o: kmer_dump.cpp kmer_dump.h
$(CC) $(CPPFLAGS) -c kmer_dump.cpp $(USER_LIBS)
thread_pool.o: thread_pool.cpp kmer_dump.h
$(CC) $(CPPFLAGS) -c thread_pool.cpp $(USER_LIBS)
This is the error I get.
/usr/bin/ld: thread_pool.o: undefined reference to symbol 'pthread_create##GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
According to the man page of g++, you should include also in the compilation the flag -pthread:
-pthread
Define additional macros required for using the POSIX threads
library. You should use this option consistently for both
compilation and linking. This option is supported on
GNU/Linux targets, most other Unix derivatives, and also on
x86 Cygwin and MinGW targets.
I am trying to compile this app using its makefile on WSL. But I get the following error:
g++ -g -Wall -ansi pendulumSystem.o TimeStepper.o particleSystem.o ClothSystem.o simpleSystem.o camera.o main.o vecmath/src/Vector3f.o vecmath/src/Vector2f.o vecmath/src/Matrix3f.o vecmath/src/Matrix4f.o vecmath/src/Vector4f.o vecmath/src/Quat4f.o vecmath/src/Matrix2f.o -o a3 -L. -lRK4 -lglut -lGL -lGLU
/usr/bin/ld: ./libRK4.a(RK4.o): relocation R_X86_64_32 against symbol `__gxx_personality_v0##CXXABI_1.3' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: ./libRK4.a(RK4.o): relocation R_X86_64_PC32 against symbol `_Znwm##GLIBCXX_3.4' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:15: a3] Error 1
I tried editing my makefile to include the flag like below, but it still gives me the same error message.
INCFLAGS = -I vecmath/include
INCFLAGS += -I /usr/include/GL
LINKFLAGS = -L. -lRK4 -lglut -lGL -lGLU
CFLAGS = -g -Wall -ansi -fPIE
CC = g++
SRCS = $(wildcard *.cpp)
SRCS += $(wildcard vecmath/src/*.cpp)
OBJS = $(SRCS:.cpp=.o)
PROG = a3
all: $(SRCS) $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $# $(LINKFLAGS)
.cpp.o:
$(CC) $(CFLAGS) $< -c -o $# $(INCFLAGS)
depend:
makedepend $(INCFLAGS) -Y $(SRCS)
clean:
rm $(OBJS) $(PROG)
Could it be that the provided libRK4.a file was not compiled with the -fPIE flag?
environment
ubuntu 18.04 (a virtual environment created by vagrant)
gcc5.5.0
I'm trying to build my own little OS.
I'm writing the kernel in C++/NASM.
I'm going to compile each of the several C++ files that make up the kernel and then link them together to create an executable file. (This is because the entry point of my own kernel is not "main", so I dare not link at the same time as compiling)
Error
The compilation of each C++ file will run without any problems and each object file will be created.
However, I get the following error in linking the object files.
But I understand that a ".a" file is a static object, not a dynamic object, so I can not understand why I'm getting this error.
I'd appreciate it if you could let me know.
ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'
Here's the full text of the log
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/hoge.o -c src/hoge.cpp
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/huga.o -c src/huga.cpp
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/piyo.o -c src/piyo.cpp
mkdir -p ./obj
nasm -f elf64 -o obj/assm.o src/assm.asm
ld --entry <ENTRY_POINT> --static -o ./ELF/kernel.elf ./obj/hoge.o ./obj/huga.o ./obj/piyo.o ./obj/assm.o -lc -lc++ -lc++abi -L/usr/lib/x86_64-linux-gnu
ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'
Makefile:12: recipe for target 'ELF/kernel.elf' failed
make: *** [ELF/kernel.elf] Error 1
Makefile
COMPILER = g++
CFLAGS = -O2 -g -MMD -Wall
INCLUDE = -I./include
TARGET = ./ELF/kernel.elf
SRCDIR = ./src
SOURCES := $(shell find $(SRCDIR) -name *.cpp -or -name *.c -or -name *.asm)
OBJDIR = ./obj
OBJECTS = $(OBJDIR)/hoge.o $(OBJDIR)/huga.o $(OBJDIR)/piyo.o $(OBJDIR)/assm.o
DEPENDS = $(OBJECTS:.o=.d)
LDFLAGS = --entry <ENTRY_POINT> --static
$(TARGET): $(OBJECTS)
ld $(LDFLAGS) -o $(TARGET) $(OBJECTS) -lc -lc++ -lc++abi -L/usr/lib/x86_64-linux-gnu
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
-mkdir -p $(OBJDIR)
$(COMPILER) $(CFLAGS) $(INCLUDE) -o $# -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.asm
-mkdir -p $(OBJDIR)
nasm -f elf64 -o $# $<
all: clean $(TARGET)
clean:
rm -rf $(OBJECTS) $(DEPENDS) $(TARGET)
-include $(DEPENDS)
I have previously write a compilation line which is working.
Howewer, my Makefile, which generates more or less the same thing, isn't successfully compiling.
Command line (working) :
sh3eb-elf-gcc -m3 -mb -ffreestanding -nostdlib -T addin.ld src/crt0.s src/BTKOM.cpp src/bluetooth.cpp src/syscall.s -o addin.elf -Iinclude -L libs/ -lgcc -lmonochrome -lfx -O2 -fno-exceptions
Makefile :
CC = sh3eb-elf-gcc
SRCDIR = src
INCLDIR = include
LIBDIR = libs
EXTENSIONS = c cpp s
LIBS = -lgcc -lmonochrome -lfx
WFLAGS = -Wall
CFLAGS = -I $(INCLDIR) $(WFLAGS)
LFLAGS = -m3 -mb -ffreestanding -nostdlib -T addin.ld -L $(LIBDIR) $(LIBS) -O2 -fno-exceptions
SRCS := $(SRCS) $(foreach EXT,$(EXTENSIONS),$(wildcard $(SRCDIR)/*.$(EXT)))
OBJS := $(OBJS) $(foreach EXT,$(EXTENSIONS),$(patsubst $(SRCDIR)/%.$(EXT),%.o,$(wildcard $(SRCDIR)/*.$(EXT))))
OUT = addin
all : $(OUT).elf
$(OUT).elf : $(OBJS)
$(CC) $(LFLAGS) -o $# $^
$(OBJS) : $(SRCDIR)/$(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
clean:
rm -f *.o
cleaner:
rm -f *.o $(OUT).elf $(OUT).g1a $(OUT).bin
Generated lines from makefile :
sh3eb-elf-gcc -I include -Wall -c src/MonochromeLib.c src/BTKOM.cpp src/bluetooth.cpp src/syscall.s src/crt0.s
sh3eb-elf-gcc -m3 -mb -ffreestanding -nostdlib -T addin.ld -L libs -lgcc -lmonochrome -lfx -O2 -fno-exceptions -o addin.elf MonochromeLib.o BTKOM.o bluetooth.o syscall.o crt0.o
Output :
BTKOM.o: In function `_main':
BTKOM.cpp:(.text+0xc4): undefined reference to `_memset'
BTKOM.cpp:(.text+0xec): undefined reference to `_GetKey'
bluetooth.o: In function `Bluetooth::Bluetooth()':
bluetooth.cpp:(.text+0xa0): undefined reference to `_srand'
bluetooth.cpp:(.text+0xa4): undefined reference to `_rand'
bluetooth.cpp:(.text+0xac): undefined reference to `_memcpy'
...
There's a reason the built-in linking rule is defined as
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $#
LINK.o is
$(CC) $(LDFLAGS) $(TARGET_ARCH)
You should find it works by rewriting your makefile as
LDLIBS := -lgcc -lmonochrome -lfx
LDFLAGS := -nostdlib -T addin.ld -L libs
$(OUT).elf: $(OBJS)
$(LINK.o) $^ $(LDLIBS) -o $#
Note that -O2, ffreestanding and -fno-exceptions are compilation options, not linking options (and I think -m3 and -mb are as well).
I am currently getting back in to c++. I have been running into a problem building my application.
When i run make the output becomes:
g++ -c -Wall -I headers/ -I ../libs/inc/SDL2 -L ../libs/lib/SDL2 -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL2 -lGL -lSDL2 -lSDL2main Debug.cpp -o Debug.o
g++ -c -Wall -I headers/ -I ../libs/inc/SDL2 -L ../libs/lib/SDL2 -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL2 -lGL -lSDL2 -lSDL2main GameLoop.cpp -o GameLoop.o
g++ -c -Wall -I headers/ -I ../libs/inc/SDL2 -L ../libs/lib/SDL2 -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL2 -lGL -lSDL2 -lSDL2main Main.cpp -o Main.o
g++ -c -Wall -I headers/ -I ../libs/inc/SDL2 -L ../libs/lib/SDL2 -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL2 -lGL -lSDL2 -lSDL2main -o GAME Debug.o GameLoop.o Main.o
g++: warning: Debug.o: linker input file unused because linking not done
g++: warning: GameLoop.o: linker input file unused because linking not done
g++: warning: Main.o: linker input file unused because linking not done
The file structure of my project
Makefile
Main.cpp
GameLoop.cpp
Debug.cpp
headers/
Main.h
GameLoop.h
Debug.h
Makefile:
CC := g++
TARGET := GAME
SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp, %.o, $(SOURCES))
DEPS := $(wildcard headers/*.h)
CPPFLAGS := -I ../libs/inc/SDL2 -L ../libs/lib/SDL2 $(shell sdl2-config --libs) -lGL -lSDL2 -lSDL2main
CFLAGS := -c -Wall -I headers/
##$(info OBJECTS= $(OBJECTS) :: SOURCES= $(SOURCES) :: EXECUTABLEOUT= $(TARGET))
default: $(TARGET)
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $(CPPFLAGS) $< -c -o $#
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
RAW Paste Data
CC := g++
TARGET := GAME
SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp, %.o, $(SOURCES))
DEPS := $(wildcard headers/*.h)
CPPFLAGS := -I ../libs/inc/SDL2 -L ../libs/lib/SDL2 $(shell sdl2-config --libs) -lGL -lSDL2 -lSDL2main
CFLAGS := -c -Wall -I headers/
##$(info OBJECTS= $(OBJECTS) :: SOURCES= $(SOURCES) :: EXECUTABLEOUT= $(TARGET))
default: $(TARGET)
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $(CPPFLAGS) $< -c -o $#
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
Currently been looking at over 60 answers on this page (and others) with no luck. :/
All your g++ calls use the -c option. From GCC's help:
-c Compile and assemble, but do not link
Your last g++ call should not have the -c option. The reason you have it is because you have specified it for all your CFLAGS:
CFLAGS := -c -Wall -I headers/
Removing it from there should fix your problem.
Remove the -c flag from the last line where you make the executable.
From Man page for g++:
-c Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.