Can't compile CUDA + OpenGL program on Mac OS X El Capitan - linux

I am writing a program that includes OpenGL and CUDA codes at the university and i can run it with Ubuntu Linux. The program has got many dependencies so i use a makefile and when i'm at the university with Linux i have no problems. Yesterday i tried running it on my MacBook at home and it didn't run. I set libraries paths properly, but when i try to compile using the makefile i get the following lines:
MBP-di-Nicolo:MATRIX_TEST Nico$ make
/Developer/NVIDIA/CUDA-7.5/bin/nvcc -ccbin g++ -m64 -Xcompiler -g -Xcompiler -arch -Xcompiler x86_64 -g -G -Xlinker -rpath -Xlinker /Developer/NVIDIA/CUDA-7.5/lib -Xlinker -framework -Xlinker GLUT -o Matrix_test my_utils2.o Matrix_test.o Matrix.o -L/System/Library -L/System/Library/Frameworks/OpenGL.framework/Libraries -lGL -lGLU ../../common/lib/darwin/libGLEW.a -L. -lrt
nvlink fatal : Could not find fatbin in 'my_utils2.o'
nvlink fatal : elfLink internal error
make: *** [Matrix_test] Error 1
MBP-di-Nicolo:MATRIX_TEST Nico$
Here's the makefile:
PROGNAME = Matrix_test
#PROGNAME2 = read_file
CC = g++
include ./findcudalib.mk
# Location of the CUDA Toolkit
CUDA_PATH ?= /Developer/NVIDIA/CUDA-7.5
#DEK_SRC = ../pure-dek/src
#DEK_INCLUDE = -I../pure-dek/include
# internal flags
NVCCFLAGS := -m${OS_SIZE}
#NVCCFLAGS := -m${OS_SIZE} --keep
CCFLAGS := -g
NVCCLDFLAGS := -g -G
LDFLAGS :=
# Extra user flags
EXTRA_NVCCFLAGS ?=
EXTRA_NVCCLDFLAGS ?=
EXTRA_LDFLAGS ?=
EXTRA_CCFLAGS ?=
# OS-specific build flags
ifneq ($(DARWIN),)
LDFLAGS += -rpath $(CUDA_PATH)/lib
CCFLAGS += -arch $(OS_ARCH) $(STDLIB)
else
ifeq ($(OS_ARCH),armv7l)
ifeq ($(abi),gnueabi)
CCFLAGS += -mfloat-abi=softfp
else
# default to gnueabihf
override abi := gnueabihf
LDFLAGS += --dynamic-linker=/lib/ld-linux-armhf.so.3
CCFLAGS += -mfloat-abi=hard
endif
endif
endif
ifeq ($(ARMv7),1)
NVCCFLAGS += -target-cpu-arch ARM
ifneq ($(TARGET_FS),)
CCFLAGS += --sysroot=$(TARGET_FS)
LDFLAGS += --sysroot=$(TARGET_FS)
LDFLAGS += -rpath-link=$(TARGET_FS)/lib
LDFLAGS += -rpath-link=$(TARGET_FS)/usr/lib
LDFLAGS += -rpath-link=$(TARGET_FS)/usr/lib/arm-linux-$(abi)
endif
endif
# Debug build flags
ifeq ($(dbg),1)
NVCCFLAGS += -g -G
TARGET := debug
else
TARGET := release
endif
ALL_CCFLAGS :=
ALL_CCFLAGS += $(NVCCFLAGS)
ALL_CCFLAGS += $(addprefix -Xcompiler ,$(CCFLAGS))
ALL_CCFLAGS += $(EXTRA_NVCCFLAGS)
ALL_CCFLAGS += $(addprefix -Xcompiler ,$(EXTRA_CCFLAGS))
ALL_LDFLAGS :=
ALL_LDFLAGS += $(ALL_CCFLAGS)
ALL_LDFLAGS += $(NVCCLDFLAGS)
ALL_LDFLAGS += $(addprefix -Xlinker ,$(LDFLAGS))
ALL_LDFLAGS += $(EXTRA_NVCCLDFLAGS)
ALL_LDFLAGS += $(addprefix -Xlinker ,$(EXTRA_LDFLAGS))
# Common includes and paths for CUDA
EXT_LIB = /System/Library
INCLUDES :=
LIBRARIES := -L$(EXT_LIB)
# Makefile include to help find GL Libraries
EXEC ?=
include ./findgllib.mk
# OpenGL specific libraries
ifneq ($(DARWIN),)
# Mac OSX specific libraries and paths to include
LIBRARIES += -L/System/Library/Frameworks/OpenGL.framework/Libraries
LIBRARIES += -lGL -lGLU ../../common/lib/darwin/libGLEW.a
ALL_LDFLAGS += -Xlinker -framework -Xlinker GLUT
else
LIBRARIES += -L../../common/lib/$(OSLOWER)/$(OS_ARCH) $(GLLINK)
#LIBRARIES += -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread -ldl -lGLEW -lglut -lGLU
LIBRARIES += -lglui -lglut -lGLU -lGL -lX11 -lXi -lXmu -lGLEW
endif
################################################################################
# CUDA code generation flags
ifneq ($(OS_ARCH),armv7l)
GENCODE_SM10 := -gencode arch=compute_11,code=sm_11
endif
GENCODE_SM10 := -gencode arch=compute_11,code=sm_11
GENCODE_SM20 := -gencode arch=compute_20,code=sm_20
GENCODE_SM30 := -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=\"sm_35,compute_35\"
GENCODE_FLAGS := $(GENCODE_SM11) $(GENCODE_SM20) $(GENCODE_SM30)
################################################################################
# Target rules
all: build
build: $(PROGNAME)
my_utils2.o: my_utils2.cu my_utils2.h
$(NVCC) $(INCLUDES) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -o $# -c $<
Matrix.o: Matrix.cu Matrix.h my_utils2.h
$(NVCC) $(INCLUDES) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -o $# -c $<
Matrix_test.o: Matrix_test.cu my_utils2.h
$(NVCC) $(INCLUDES) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -o $# -c $<
$(PROGNAME): my_utils2.o Matrix_test.o Matrix.o
$(NVCC) $(ALL_LDFLAGS) -o $# $+ $(LIBRARIES) -L. -lrt
mkdir -p ./bin/$(OS_ARCH)/$(OSLOWER)/$(TARGET)$(if $(abi),/$(abi))
cp $# ./bin/$(OS_ARCH)/$(OSLOWER)/$(TARGET)$(if $(abi),/$(abi))
run: build
./$(PROGNAME)
clean:
rm -f *.o
# rm -rf ./bin/$(OS_ARCH)/$(OSLOWER)/$(TARGET)$(if $(abi),/$(abi))/mergeSort
clobber: clean
I didn't modify the makefile used for Linux, except for two lines (the following are the old ones):
# Location of the CUDA Toolkit
CUDA_PATH ?= "/usr/local/cuda-7.5"
# Common includes and paths for CUDA
EXT_LIB = /usr/local/lib
Could you help me please?
Thanks a lot!!

You don't have to use nvcc to link the final program. In fact I strongly advise against it. nvcc should be used for compiling .cu files only and the rest be left to gcc/g++/clang.
In general it's a bad idea to force nvcc into using a particular compiler. Just let it choose its default. I don't see in the Makefile you posted (it's likely in findcuda.mk) the definition for variable NVCC, I suspect that there the --ccbin flag is configured.
Furthermore in MacOS X OpenGL is covered by the OpenGL framework. The libraries libGL/libGLU are there for support programs running through an X11 server (which is available in MacOS X), but the X11/GLX/OpenGL support of MacOS X is a compatibility layer and will not support CUDA.
Hence I suggest you change as following:
LIBRARIES += ../../common/lib/darwin/libGLEW.a
LDFLAGS += -framework GLUT -framework OpenGL
all: build install
$(PROGNAME): my_utils2.o Matrix_test.o Matrix.o
$(LD) $(LDFLAGS) -o $# $+ $(LIBRARIES) -L.
install: $(PROGNAME)
mkdir -p ./bin/$(OS_ARCH)/$(OSLOWER)/$(TARGET)$(if $(abi),/$(abi))
cp $# ./bin/$(OS_ARCH)/$(OSLOWER)/$(TARGET)$(if $(abi),/$(abi))

Related

How does make use variables when expanding and compiling before linking?

Info:
Linux watvde0453 3.10.0-1062.1.1.el7.x86_64 #1 SMP Fri Sep 13 22:55:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Hi
I have been playing around with a make file to allow builds of shared, static libraries and an exe (and also to get some sort of understanding about how it works) and came across some behavior I do not understand.
I was trying to separate out the flags used for lib / exe into separate variables, but when using a line to compile and link all in one it looks like only the CFLAGS variable is being included for the compile step.
When using the following makefile:
LIBCFLAGS := -fPIC
CFLAGS := -O3 -g -Wall -Werror
CC := gcc
SRCS=hashfunction.c hashtable.c hashtablelinkedlist.c
OBJS=hashfunction.o hashtable.o hashtablelinkedlist.o
LIBSO = lib$(NAME).so
libso: $(OBJS)
$(CC) $(LIBCFLAGS) $(CFLAGS) -shared -o $(LIBSO) $(OBJS)
I get the following output when running the make command for libso:
$ make libso
gcc -O3 -g -Wall -Werror -c -o hashfunction.o hashfunction.c
gcc -O3 -g -Wall -Werror -c -o hashtable.o hashtable.c
gcc -O3 -g -Wall -Werror -c -o hashtablelinkedlist.o hashtablelinkedlist.c
gcc -fPIC -O3 -g -Wall -Werror -shared -o lib.so hashfunction.o hashtable.o hashtablelinkedlist.o
/tools/oss/packages/x86_64-centos7/binutils/default/bin/ld: hashtable.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
hashtable.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: libso] Error 1
I can get it all working by sticking all the flags in CFLAGS, but I was wondering if anyone could explain what make is doing underneath ?
It looks like the $(LIBCFLAGS) is being ignored for the implicit compile lines, but $(CFLAGS) is not. Is CFALGS used implicitly by make for all compilations ?
You can see all the built-in rules make knows about by running make -p -f/dev/null. There you'll see:
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
which is the built-in rule make uses to create a .o file from a .c file. Looking elsewhere in the output you'll see:
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
so these are the variables make uses to compile .c files into .o files.

Makefile for OpenGL with glad on Linux

I want to use glad in my OpenGL project but I am not quite sure how to create the Makefile for it. I downladed glad from the webservice and moved the directories from include/ (glad/ and KHR/) to /usr/include/ (Now emacs sees the library) and the glad.c file to the root of my project (which at the moment contatns only a demo source.cpp file).
I have this Makefile:
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux)
COMPILER = g++
FLAGS = -std=c++1y -pedantic -Wall
GL_FLAGS = -lGL -lglfw
endif
ifeq ($(UNAME_S), Darwin)
COMPILER = clang++
FLAGS = -std=c++1y -stdlib=libc++ -pedantic -Wall
GL_FLAGS = -lGLEW -framework OpenGL -lm
endif
FILES = $(wildcard *.cpp)
APP_NAME = opengl-app
all: main
main: $(FILES)
$(COMPILER) $(FLAGS) $(FILES) glad.c -o $(APP_NAME) $(GL_FLAGS)
.PHONY: clean run
clean:
rm opengl-app
run: opengl-app
./opengl-app
This when executed gives these errors:
/usr/bin/ld: /tmp/cc0DUjDZ.o: undefined reference to symbol 'dlclose##GLIBC_2.2.5'
/usr/lib/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Any help with the makefile will be greatly appreciated.
As mentioned in the comments by #G.M. glad makes use of dlopen/dlclose, methods used to load shared objects in Linux.
The Makefile should add the link flag to use libdl.so. The final result should be something like this:
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux)
COMPILER = g++
FLAGS = -std=c++1y -pedantic -Wall
GL_FLAGS = -lGL -lglfw
endif
ifeq ($(UNAME_S), Darwin)
COMPILER = clang++
FLAGS = -std=c++1y -stdlib=libc++ -pedantic -Wall
GL_FLAGS = -lGLEW -framework OpenGL -lm
GLAD_FLAGS = -ldl
endif
FILES = $(wildcard *.cpp)
APP_NAME = opengl-app
all: main
main: $(FILES)
$(COMPILER) $(FLAGS) $(FILES) glad.c -o $(APP_NAME) $(GL_FLAGS) $(GLAD_FLAGS)
.PHONY: clean run
clean:
rm opengl-app
run: opengl-app
./opengl-app

Makefile for Linux and Mac with address sanitizer

I am trying to write a makefile that I can use on linux and mac that builds with an address sanitizer. This works on my vagrant instance:
CC = gcc
ASAN_FLAGS = -fsanitize=address -fno-omit-frame-pointer -Wno-format-security
ASAN_LIBS = -static-libasan
CFLAGS := -Wall -Werror --std=gnu99 -g3
LDFLAGS += -lpthread
all: hello
hello: tiny_queue.o hello.o
$(CC) -o $# $(CFLAGS) $(ASAN_FLAGS) $(CURL_CFLAGS) $^ $(LDFLAGS) $(CURL_LIBS) $(ASAN_LIBS)
This works on ubuntu/trusty64 but fails on my mac with
$ make
gcc -Wall -Werror --std=gnu99 -g3 -I/opt/X11/include -c -o hello.o hello.c
gcc -o hello -Wall -Werror --std=gnu99 -g3 -fsanitize=address -fno-omit-frame-pointer -Wno-format-security tiny_queue.o hello.o -lpthread -static-libasan
clang: error: unknown argument: '-static-libasan'
make: *** [hello] Error 1
Does anyone know how to write a compatible makefile for the mac and linux?
p.s. I'm very new to C, sorry if this question is super basic.
CC = gcc
ASAN_FLAGS = -fsanitize=address -fno-omit-frame-pointer -Wno-format-security
ASAN_LIBS = -static-libasan
CFLAGS := -Wall -Werror --std=gnu99 -g3
LDFLAGS += -lpthread
all: hello
hello: tiny_queue.o hello.o
$(CC) -o $# $(CFLAGS) $(ASAN_FLAGS) $(CURL_CFLAGS) $^ $(LDFLAGS) $(CURL_LIBS) $(ASAN_LIBS)
You should not specify an Asan library (or a UBsan library, for that matter). Since you are using the compiler driver to drive link, just use -fsanitize=address (this is the recommended way of doing it). Do not add -static-libasan. The compiler driver will add the proper libraries for you.

Firefox not loading XPCOM Component under Fedora

I am trying to build simple XPCOM component for Firefox 3.6.13 under LINUX operating system. I successfully compiled the component using Xulrunner SDK 1.9.2.13. I kept it under components directory. But when I start my firefox firefox console shows error
'Failed to load XPCOM component:
/home/mypc/.mozilla/firefox/cxsm79p6.default/extensions/{1280606b-2510-4fe0-97ef-9b5a22eafe80}/components/MyComponent.so
By referring to this link https://developer.mozilla.org/en/Troubleshooting_XPCOM_components_registration, I followed instructions under title 'Linux-specific hints'. It says to use special linking time option -Wl,-z,defs while linking. So I added these options but now while compiling its showing error as
make: Warning: File `Makefile' has modification time 0.25 s in the future
c++ -Os -Wall -o MyComponent.so
-include xpcom-config.h -DXPCOM_GLUE_USE_NSPR -I /mnt/hgfs/C/Users/sunil/SDKS/LINUX/xulrunner-sdk/include
-I./ -L /mnt/hgfs/C/Users/sunil/SDKS/LINUX/xulrunner-sdk/lib
-lxpcomglue_s -lxpcom -lnspr4 -fno-rtti -fno-exceptions -shared -Wl,-z,defs MyComponent.cpp MyComponentModule.cpp
/tmp/ccMGUTql.o: In function
MyComponent::QueryInterface(nsID
const&, void**)':
MyComponent.cpp:(.text+0x9b):
undefined reference to
NS_TableDrivenQI(void*, QITableEntry
const*, nsID const&, void**)'
/tmp/ccbkZLTz.o: In function
NSGetModule':
MyComponentModule.cpp:(.text+0x15):
undefined reference to
NS_NewGenericModule2(nsModuleInfo
const*, nsIModule*)' collect2: ld
returned 1 exit status make: **
[build] Error 1
My New makefile is as follows
CXX = c++
CPPFLAGS += -fno-rtti \
-fno-exceptions \
-shared \
-Wl,-z,defs
# Change this to point at your Gecko SDK directory.
GECKO_SDK_PATH =/mnt/hgfs/C/Users/sunil/SDKS/LINUX/xulrunner-sdk
# GCC only define which allows us to not have to #include mozilla-config
# in every .cpp file. If your not using GCC remove this line and add
# #include "mozilla-config.h" to each of your .cpp files.
GECKO_CONFIG_INCLUDE = -include xpcom-config.h
GECKO_DEFINES = -DXPCOM_GLUE_USE_NSPR
GECKO_INCLUDES = -I $(GECKO_SDK_PATH)/include
GECKO_LDFLAGS = -L $(GECKO_SDK_PATH)/lib -lxpcomglue_s -lxpcom \
-lnspr4
FILES = MyComponent.cpp MyComponentModule.cpp
TARGET = MyComponent.so
build:
$(CXX) -Os -Wall -o $(TARGET) $(GECKO_CONFIG_INCLUDE) $(GECKO_DEFINES) $(GECKO_INCLUDES) -I./ $(GECKO_LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(FILES)
chmod +x $(TARGET)
strip $(TARGET)
clean:
rm $(TARGET)
Can somebody help me get around this ?
I think you get this error if your libraries aren't specified correctly. One of these lines might fix it:
GECKO_LDFLAGS = -L$(GECKO_SDK_PATH)/lib -L$(GECKO_SDK_PATH)/bin -Wl,-rpath-link,$(GECKO_SDK_PATH)/bin -lxpcomglue_s -lxpcom -lnspr4
or
$(CXX) -Os -Wall -o $(TARGET) $(GECKO_CONFIG_INCLUDE) $(GECKO_DEFINES) $(GECKO_INCLUDES) -I./ $(CPPFLAGS) $(CXXFLAGS) $(FILES) $(GECKO_LDFLAGS)

Linking OpenSSL libraries to a program

I have built OpenSSL from source (an intentionally old version; built with ./config && make && make test) and would prefer to use what I have built without doing make install to link against my program.
The command that's failing is:
gcc -Wall -Wextra -Werror -static -Lopenssl/openssl-0.9.8k/ -lssl -lcrypto
-Iopenssl/openssl-0.9.8k/include -o myApp source1.o source2.o common.o`
And I receive a series of errors similar to:
common.c:(.text+0x1ea): undefined reference to `SSL_write'
This makes me think there's something funky with my OpenSSL. If I omit -Lopenssl/openssl-0.9.8k/ from my command, the error changes to being unable to:
/usr/bin/ld: cannot find -lssl
/usr/bin/ld: cannot find -lcrypto
Am I compiling OpenSSL incorrectly? Or how should I best resolve this?
Silly "Linux-isms" strike again! Apparently, I need to change my command such that the -L and -l stuff is at the end like (despite what man gcc seems to indicate):
gcc -Wall -Wextra -Werror -static -o myApp source1.o source2.o common.o -Lopenssl/openssl-0.9.8k/ -lssl -lcrypto -Iopenssl/openssl-0.9.8k/include
Why don't you want to use make install? It can copy generated binaries in the directory you want if you previously passed it to ./configure --prefix $HOME/target_library_install_directory
If you used this trick with every library you build and install, you could then add the target directory to the LIBRARY_PATH environment variable and avoid using -L option.
If you use Autotools, or you are building an Autools project like cURL, then you should be able to use pkg-config. The idea is the Autotools package will read OpenSSL's package configuration and things will "just work" for you.
The OpenSSL package configuration library name is openssl.
You would use it like so in a makefile based project.
%.o: %.c
$(CC) -o $# -c `pkg-config --cflags openssl` $^
target: foo.o bar.o baz.o
$(CC) -o $# `pkg-config --libs openssl` $^
Also see How to use pkg-config in Make and How to use pkg-config to link a library statically.
Another approach is to use pkg-config to preserve compatibility. This is an example of makefile when needs to link OpenSSL.
CC = gcc
CFLAGS = \
-I. \
-D_GNU_SOURCE=1
LDFLAGS = `pkg-config --libs inih`
LDFLAGS += `pkg-config --libs libcurl`
LDFLAGS += `pkg-config --libs liburiparser`
LDFLAGS += `pkg-config --libs openssl`
# Executable
foo: foo.o
$(CC) -o $# $^ $(LDFLAGS)
foo.o: foo.c
$(CC) -c $(CFLAGS) $< -o $#

Resources