Unresolve External Symbol CUDA C++ (Kernel to Kernel Calls) [duplicate] - c++

This is my first program using Dynamic Parallelism and I am unable to compile the code. I need to be able to run this for my research project at college and any help will be most appreciated:
I get the following error:
/cm/shared/apps/cuda50/toolkit/5.0.35/bin/nvcc -m64 -dc -gencode arch=compute_35,code=sm_35 -rdc=true -dlink -po maxrregcount=16 -I/cm/shared/apps/cuda50/toolkit/5.0.35 -I. -I.. -I../../common/inc -o BlackScholes.o -c BlackScholes.cu
g++ -m64 -I/cm/shared/apps/cuda50/toolkit/5.0.35 -I. -I.. -I../../common/inc -o BlackScholes_gold.o -c BlackScholes_gold.cpp
g++ -m64 -o BlackScholes BlackScholes.o BlackScholes_gold.o -L/cm/shared/apps/cuda50/toolkit/5.0.35/lib64 -lcudart -lcudadevrt
BlackScholes.o: In function `__sti____cudaRegisterAll_47_tmpxft_000059cb_00000000_6_BlackScholes_cpp1_ii_c58990ec()':
tmpxft_000059cb_00000000-3_BlackScholes.cudafe1.cpp:(.text+0x1354): undefined reference to `__cudaRegisterLinkedBinary_47_tmpxft_000059cb_00000000_6_BlackScholes_cpp1_ii_c58990ec'
collect2: ld returned 1 exit status
make: *** [BlackScholes] Error 1
I have one cpp file, one cu file and one cuh file. Important portions of my makefile are below:
# CUDA code generation flags
#GENCODE_SM10 := -gencode arch=compute_10,code=sm_10
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
GENCODE_SM35 := -gencode arch=compute_35,code=sm_35
#GENCODE_FLAGS := $(GENCODE_SM10) $(GENCODE_SM20) $(GENCODE_SM30)
GENCODE_FLAGS := $(GENCODE_SM35)
# OS-specific build flags
ifneq ($(DARWIN),)
LDFLAGS := -Xlinker -rpath $(CUDA_LIB_PATH) -L$(CUDA_LIB_PATH) -lcudart -lcudadevrt
CCFLAGS := -arch $(OS_ARCH)
else
ifeq ($(OS_SIZE),32)
LDFLAGS := -L$(CUDA_LIB_PATH) -lcudart -lcudadevrt
CCFLAGS := -m32
else
LDFLAGS := -L$(CUDA_LIB_PATH) -lcudart -lcudadevrt
CCFLAGS := -m64
endif
endif
# OS-architecture specific flags
ifeq ($(OS_SIZE),32)
NVCCFLAGS := -m32 -dc
else
NVCCFLAGS := -m64 -dc
endif
# Debug build flags
ifeq ($(dbg),1)
CCFLAGS += -g
NVCCFLAGS += -g -G
TARGET := debug
else
TARGET := release
endif
# Common includes and paths for CUDA
INCLUDES := -I$(CUDA_INC_PATH) -I. -I.. -I../../common/inc
# Additional parameters
MAXRREGCOUNT := -po maxrregcount=16
# Target rules
all: build
build: BlackScholes
BlackScholes.o: BlackScholes.cu
$(NVCC) $(NVCCFLAGS) $(EXTRA_NVCCFLAGS) $(GENCODE_FLAGS) -rdc=true -dlink $(MAXRREGCOUNT) $(INCLUDES) -o $# -c $<
BlackScholes_gold.o: BlackScholes_gold.cpp
$(GCC) $(CCFLAGS) $(INCLUDES) -o $# -c $<
BlackScholes: BlackScholes.o BlackScholes_gold.o
$(GCC) $(CCFLAGS) -o $# $+ $(LDFLAGS) $(EXTRA_LDFLAGS)
mkdir -p ../../bin/$(OSLOWER)/$(TARGET)
cp $# ../../bin/$(OSLOWER)/$(TARGET)
enter code here
run: build
./BlackScholes

When using the host linker (g++) for final linking of your executable, and when using relocatable device code (nvcc -dc), it's necessary to do an intermediate device code link step.
From the documentation:
If you want to invoke the device and host linker separately, you can do:
nvcc –arch=sm_20 –dc a.cu b.cu
nvcc –arch=sm_20 –dlink a.o b.o –o link.o
g++ a.o b.o link.o –L<path> -lcudart
Since you are specifying -dc on the compile line, you are getting a compile-only operation (just as if you had specified -c to g++).
Here's a modified/condensed Makefile that should show you what is involved:
GENCODE_SM35 := -gencode arch=compute_35,code=sm_35
GENCODE_FLAGS := $(GENCODE_SM35)
LDFLAGS := -L/usr/local/cuda/lib64 -lcudart -lcudadevrt
CCFLAGS := -m64
NVCCFLAGS := -m64 -dc
NVCC := nvcc
GCC := g++
# Debug build flags
ifeq ($(dbg),1)
CCFLAGS += -g
NVCCFLAGS += -g -G
TARGET := debug
else
TARGET := release
endif
# Common includes and paths for CUDA
INCLUDES := -I/usr/local/cuda/include -I. -I..
# Additional parameters
MAXRREGCOUNT := -po maxrregcount=16
# Target rules
all: build
build: BlackScholes
BlackScholes.o: BlackScholes.cu
$(NVCC) $(NVCCFLAGS) $(EXTRA_NVCCFLAGS) $(GENCODE_FLAGS) $(MAXRREGCOUNT) $(INCLUDES) -o $# $<
$(NVCC) -dlink $(GENCODE_FLAGS) $(MAXRREGCOUNT) -o bs_link.o $#
BlackScholes_gold.o: BlackScholes_gold.cpp
$(GCC) $(CCFLAGS) $(INCLUDES) -o $# -c $<
BlackScholes: BlackScholes.o BlackScholes_gold.o bs_link.o
$(GCC) $(CCFLAGS) -o $# $+ $(LDFLAGS) $(EXTRA_LDFLAGS)
run: build
./BlackScholes

Related

Barrier file not found (C++ Makefile)

I am trying to compile a project however the make command returns with the error
fatal error: 'barrier' file not found
and after changing clang versions and changing my platform, nothing seems to help. Therefore I would like to ask for assistance regarding this issue.
Here is my makefile:
CC = clang
CXX = clang++
CFLAGS := $(CFLAGS) -g -O3 -Wall -Wextra -pedantic -Werror -std=c18 -pthread
CXXFLAGS := $(CXXFLAGS) -stdlib=libc++ -g -O3 -Wall -Wextra -pedantic -Werror -std=c++20 -pthread
all: project
SRCS = main.cpp input.cpp output.cpp project.cpp
project: $(SRCS:%=%.o)
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $#
.PHONY: clean
clean:
rm -f *.o project
DEPDIR := .deps
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$<.d
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.cpp = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
%.c.o: %.c
%.c.o: %.c $(DEPDIR)/%.c.d | $(DEPDIR)
$(COMPILE.c) $(OUTPUT_OPTION) $<
%.cpp.o: %.cpp
%.cpp.o: %.cpp $(DEPDIR)/%.cpp.d | $(DEPDIR)
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
$(DEPDIR): ; #mkdir -p $#
DEPFILES := $(SRCS:%=$(DEPDIR)/%.d) $(DEPDIR)/client.c.d
$(DEPFILES):
include $(wildcard $(DEPFILES))
EDIT
The platform details:
clang --version output:
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
OS details:
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
Full error:
clang++ -MT project.cpp.o -MMD -MP -MF .deps/project.cpp.d -stdlib=libc++ -g -O3 -Wall -Wextra -pedantic -Werror -std=c++1z -pthread -c -o project.cpp.o project.cpp
In file included from project.cpp:1:
./project.hpp:9:10: fatal error: 'barrier' file not found
#include <barrier>
^~~~~~~~~
1 error generated.
Makefile:33: recipe for target 'project.cpp.o' failed
make: *** [project.cpp.o] Error 1
EDIT-2
flag c++20 gives off error: invalid value 'c++20' in '-std=c++20'

linux C++ gmake "No rule to make target"

It's been a couple decades since I've had to manage makefiles. I've checked existing answers here, as well as googling elsewhere. When I use the target: $(BIN)/$(EXECUTABLE): $(OBJECTS)
I'm stumped as to why my makefile is failing with:
$ make
make: *** No rule to make target 'src/SRecord.o', needed by 'bin/main'. Stop.
Here's the Makefile:
# execute `make D='-g'` to make with debug symbols
DEFS := $(D)
CC := gcc $(DEFS)
CFLAGS := -std=c99 -Wall -Wextra
CXX := g++ $(DEFS)
CXXFLAGS := -std=c++17 -Wall -Wextra
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
#LIBSOURCES := $(wildcard $(LIB)/*.cpp)
#LIBOBJECTS := $(LIBSOURCES:%.cpp=%.o)
#OBJECTS := $(subst $(LIB)/,,$(LIBOBJECTS))
SOURCES := $(wildcard $(SRC)/*.cpp)
OBJECTS := $(SOURCES:%.cpp=%.o)
# SOURCES := \
# $(SRC)/main.cpp \
# $(SRC)/SerialPort.cpp \
# $(SRC)/ShadowUpdate.cpp \
# $(SRC)/SRecord.cpp
# OBJECTS := \
# $(SRC)/SerialPort.o \
# $(SRC)/ShadowUpdate.o \
# $(SRC)/SRecord.o
EXECUTABLE := main
#
# Targets
#
.PHONY: clean all
all: $(BIN)/$(EXECUTABLE)
clean:
$(RM) $(BIN)/$(EXECUTABLE)
$(RM) $(OBJECTS)
run: all
./$(BIN)/$(EXECUTABLE)
# $(BIN)/$(EXECUTABLE): $(SRC)/*
$(BIN)/$(EXECUTABLE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $#
#
# Dependencies - must be at end of makefile
#
DEPDIR := .d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.Td
POSTCOMPILE = #mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(CC) -c -o $*.o $(DEPFLAGS) $(CFLAGS) $<
$(POSTCOMPILE)
%.o: %.cpp
%.o: %.cpp $(DEPDIR)/%.d
$(CXX) -c -o $*.o $(DEPFLAGS) $(CXXFLAGS) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
It works with the commented out target: # $(BIN)/$(EXECUTABLE): $(SRC)/*
But, I want to be able to have a more complex project than simply listing all the source files as dependencies to the executable.
Here's my file tree:
src/
src/SerialPort.cpp
src/SRecord.cpp
src/ShadowUpdate.cpp
src/main.cpp
include
include/ShadowUpdate.h
include/SerialPort.h
include/SRecord.h
include/the_exo.h
bin/
bin/main
Makefile
lib/
.d/
The automatic dependency generation isn't working either, even though it is straight from GNU's website.
Think about what the % expands to in
%.o: %.cpp $(DEPDIR)/%.d
plugging in src/SRecord.o:
src/SRecord.o: src/SRecord.cpp .d/src/SRecord.d
Can you see the issue? Try the following instead
$(SRC)/%.o: $(SRC)/%.cpp $(SRC)/$(DEPDIR)/%.d
You won't need the lines that override the built-in recipes (%.o: %.cpp), get rid of them.
For clarity to anyone looking for the answer in the future, I'm posting my revised Makefile:
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
# execute `make D='-g'` to make with debug symbols
DEFS := $(D)
CC := gcc $(DEFS)
CFLAGS := -I$(INCLUDE) -std=c99 -Wall -Wextra
CXX := g++ $(DEFS)
CXXFLAGS := -I$(INCLUDE) -std=c++17 -Wall -Wextra
#LIBSOURCES := $(wildcard $(LIB)/*.cpp)
#LIBOBJECTS := $(LIBSOURCES:%.cpp=%.o)
#OBJECTS := $(subst $(LIB)/,,$(LIBOBJECTS))
SOURCES := $(wildcard $(SRC)/*.cpp)
OBJECTS := $(SOURCES:%.cpp=%.o)
EXECUTABLE := main
#
# Targets
#
.PHONY: clean all
all: $(BIN)/$(EXECUTABLE)
clean:
$(RM) $(BIN)/$(EXECUTABLE)
$(RM) $(OBJECTS)
run: all
./$(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -L$(LIB) $^ -o $#
#
# Dependencies - must be at end of makefile
#
DEPDIR := $(SRC)/.d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.Td
POSTCOMPILE = #mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(CC) -c -o $# $(DEPFLAGS) $(CFLAGS) $<
$(POSTCOMPILE)
%.o: %.cpp
$(SRC)/%.o: $(SRC)/%.cpp $(DEPDIR)/%.d
$(CXX) -c -o $# $(DEPFLAGS) $(CXXFLAGS) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
To clarify my comment to the above answer, if I comment out the "override" target (%.o: %.cpp), here's the output:
$ make clean; make
rm -f bin/main
rm -f src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/SRecord.o src/SRecord.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/SerialPort.o src/SerialPort.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/ShadowUpdate.o src/ShadowUpdate.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/main.o src/main.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -Llib src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o -o bin/main
Clearly, the dependencies are not being made. My rule was not executed.
But, with the empty %.o: %.cpp target in place, the make performs as expected:
$ make clean; make
rm -f bin/main
rm -f src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o
g++ -c -o src/SRecord.o -MT src/SRecord.o -MMD -MP -MF src/.d/SRecord.Td -Iinclude -std=c++17 -Wall -Wextra src/SRecord.cpp
g++ -c -o src/SerialPort.o -MT src/SerialPort.o -MMD -MP -MF src/.d/SerialPort.Td -Iinclude -std=c++17 -Wall -Wextra src/SerialPort.cpp
g++ -c -o src/ShadowUpdate.o -MT src/ShadowUpdate.o -MMD -MP -MF src/.d/ShadowUpdate.Td -Iinclude -std=c++17 -Wall -Wextra src/ShadowUpdate.cpp
g++ -c -o src/main.o -MT src/main.o -MMD -MP -MF src/.d/main.Td -Iinclude -std=c++17 -Wall -Wextra src/main.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -Llib src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o -o bin/main

My c++ application fails to link, and i don't know why

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.

How to merge two different Makefiles?

I have did some reading on "Merging Makefiles", one suggest I should leave the two Makefiles separate in different folders [1]. For me this look counter intuitive, because I have the following situation:
I have 3 source files (main.cpp flexibility.cpp constraints.cpp) one of them (flexibility.cpp) is making use of the COIN-OR Linear Programming library (Clp) When installing this library on my computer it makes sample Makefiles, which I have adjust the Makefile and it currently makes a good working binary.
# Copyright (C) 2006 International Business Machines and others.
# All Rights Reserved.
# This file is distributed under the Eclipse Public License.
# $Id: Makefile.in 726 2006-04-17 04:16:00Z andreasw $
##########################################################################
# You can modify this example makefile to fit for your own program. #
# Usually, you only need to change the five CHANGEME entries below. #
##########################################################################
# To compile other examples, either changed the following line, or
# add the argument DRIVER=problem_name to make
DRIVER = main
# CHANGEME: This should be the name of your executable
EXE = clp
# CHANGEME: Here is the name of all object files corresponding to the source
# code that you wrote in order to define the problem statement
OBJS = $(DRIVER).o constraints.o flexibility.o
# CHANGEME: Additional libraries
ADDLIBS =
# CHANGEME: Additional flags for compilation (e.g., include flags)
ADDINCFLAGS =
# CHANGEME: Directory to the sources for the (example) problem definition
# files
SRCDIR = .
##########################################################################
# Usually, you don't have to change anything below. Note that if you #
# change certain compiler options, you might have to recompile the #
# COIN package. #
##########################################################################
COIN_HAS_PKGCONFIG = TRUE
COIN_CXX_IS_CL = #TRUE
COIN_HAS_SAMPLE = TRUE
COIN_HAS_NETLIB = #TRUE
# C++ Compiler command
CXX = g++
# C++ Compiler options
CXXFLAGS = -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD
# additional C++ Compiler options for linking
CXXLINKFLAGS = -Wl,--rpath -Wl,/home/martijn/Downloads/COIN/coin-Clp/lib
# C Compiler command
CC = gcc
# C Compiler options
CFLAGS = -O3 -pipe -DNDEBUG -pedantic-errors -Wimplicit -Wparentheses -Wsequence-point -Wreturn-type -Wcast-qual -Wall -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD
# Sample data directory
ifeq ($(COIN_HAS_SAMPLE), TRUE)
ifeq ($(COIN_HAS_PKGCONFIG), TRUE)
CXXFLAGS += -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\"
CFLAGS += -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\"
else
CXXFLAGS += -DSAMPLEDIR=\"\"
CFLAGS += -DSAMPLEDIR=\"\"
endif
endif
# Netlib data directory
ifeq ($(COIN_HAS_NETLIB), TRUE)
ifeq ($(COIN_HAS_PKGCONFIG), TRUE)
CXXFLAGS += -DNETLIBDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatanetlib`\"
CFLAGS += -DNETLIBDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatanetlib`\"
else
CXXFLAGS += -DNETLIBDIR=\"\"
CFLAGS += -DNETLIBDIR=\"\"
endif
endif
# Include directories (we use the CYGPATH_W variables to allow compilation with Windows compilers)
ifeq ($(COIN_HAS_PKGCONFIG), TRUE)
INCL = `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --cflags clp`
else
INCL =
endif
INCL += $(ADDINCFLAGS)
# Linker flags
ifeq ($(COIN_HAS_PKGCONFIG), TRUE)
LIBS = `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --libs clp`
else
ifeq ($(COIN_CXX_IS_CL), TRUE)
LIBS = -link -libpath:`$(CYGPATH_W) /home/martijn/Downloads/COIN/coin-Clp/lib` libClp.lib
else
LIBS = -L/home/martijn/Downloads/COIN/coin-Clp/lib -lClp
endif
endif
# The following is necessary under cygwin, if native compilers are used
CYGPATH_W = echo
# Here we list all possible generated objects or executables to delete them
CLEANFILES = clp \
main.o \
flexibility.o \
constraints.o \
all: $(EXE)
.SUFFIXES: .cpp .c .o .obj
$(EXE): $(OBJS)
bla=;\
for file in $(OBJS); do bla="$$bla `$(CYGPATH_W) $$file`"; done; \
$(CXX) $(CXXLINKFLAGS) $(CXXFLAGS) -o $# $$bla $(LIBS) $(ADDLIBS)
clean:
rm -rf $(CLEANFILES)
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCL) -c -o $# `test -f '$<' || echo '$(SRCDIR)/'`$<
.cpp.obj:
$(CXX) $(CXXFLAGS) $(INCL) -c -o $# `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(SRCDIR)/$<'; fi`
.c.o:
$(CC) $(CFLAGS) $(INCL) -c -o $# `test -f '$<' || echo '$(SRCDIR)/'`$<
.c.obj:
$(CC) $(CFLAGS) $(INCL) -c -o $# `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(SRCDIR)/$<'; fi`
The other Makefile compiles a lot of code and makes use of bison and flex. This one is also made by someone else. I am able to alter this Makefile when I want to add some code. This Makefile also makes a binary.
CFLAGS=-Wall
LDLIBS=-LC:/GnuWin32/lib -lfl -lm
LSOURCES=lex.l
YSOURCES=grammar.ypp
CSOURCES=debug.cpp esta_plus.cpp heap.cpp main.cpp stjn.cpp timing.cpp tmsp.cpp token.cpp chaining.cpp flexibility.cpp exceptions.cpp
HSOURCES=$(CSOURCES:.cpp=.h) includes.h
OBJECTS=$(LSOURCES:.l=.o) $(YSOURCES:.ypp=.tab.o) $(CSOURCES:.cpp=.o)
all: solver
solver: CFLAGS+=-g -O0 -DDEBUG
solver: $(OBJECTS) main.o debug.o
g++ $(CFLAGS) -o $# $^ $(LDLIBS)
solver.release: CFLAGS+=-O5
solver.release: $(OBJECTS) main.o
g++ $(CFLAGS) -o $# $^ $(LDLIBS)
%.o: %.cpp
g++ -c $(CFLAGS) -o $# $<
lex.cpp: lex.l grammar.tab.cpp grammar.tab.hpp
flex -o$# $<
%.tab.cpp %.tab.hpp: %.ypp
bison --verbose -d $<
ifneq ($(LSOURCES),)
$(LSOURCES:.l=.cpp): $(YSOURCES:.y=.tab.h)
endif
-include $(OBJECTS:.o=.d)
clean:
rm -f $(OBJECTS) $(OBJECTS:.o=.d) $(YSOURCES:.ypp=.tab.cpp) $(YSOURCES:.ypp=.tab.hpp) $(YSOURCES:.ypp=.output) $(LSOURCES:.l=.cpp) solver solver.release 2>/dev/null
.PHONY: all clean debug release
Both of these Makefiles are, for me, hard to understand. I don't know what they exactly do. What I want is to merge the two of them so I get only one binary. The code compiled in the second Makefile should be the result. I want to add flexibility.cpp and constraints.cpp to the second Makefile, but when I do. I get the problem following problem:
flexibility.h:4:26: fatal error: ClpSimplex.hpp: No such file or directory
#include "ClpSimplex.hpp"
So the compiler can't find the Clp library. I also tried to copy-paste more code from the first Makefile into the second, but it still gives me that same error.
Q: Can you please help me with merging the two makefiles or pointing out a more elegant way?
Q: In this case is it indeed better to merge the two Makefiles?
I also tried to use cmake, but I gave upon that one quickly, because I don't know much about flex and bison.
g++ -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\" `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --cflags clp` -c -o main.o `test -f 'main.cpp' || echo './'`main.cpp
g++ -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\" `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --cflags clp` -c -o constraints.o `test -f 'constraints.cpp' || echo './'`constraints.cpp
g++ -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\" `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --cflags clp` -c -o flexibility.o `test -f 'flexibility.cpp' || echo './'`flexibility.cpp
bla=;\
for file in main.o constraints.o flexibility.o; do bla="$bla `echo $file`"; done; \
g++ -Wl,--rpath -Wl,/home/martijn/Downloads/COIN/coin-Clp/lib -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\" -o clp $bla `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --libs clp`
This is coming out of the first Makefile, looks like there are some errors in it? Printing things like echo looks really stupid.
What I want is to merge the two of them so I get only one binary.
I believe you have a complete wrong understanding what make does and what a Makefile is good for and there is a big misunderstanding what the concept of libraries, modules and programs ( binaries ) is.
As a first hint:
You can have multiple Makefiles in one directory. They can have every name you want to give them! "Makefile" is only the standard name which is searched first from the make command. Typical names are *.mk for modules of makefiles.
The next thing is, that there is no problem to call a makefile directly from make with another name. Simply use make -f xyz.mk to get this makefile in action.
The next thing is, that you can also include one makefile from another with "include".
I have not enough time to create your makefiles at all. But you should start with a little analyses:
What are your sources
What are your intermediate products / libraries / object - files
which objects will be linked to final product or libraries
which are the final products build up.
After that you can simply build your makefile toolchain. But you have start with some basic reading and some experiments with make.
I have run the first Makefile and used the output on the terminal to edit the second Makefile. I also have added the -std=c++11 flag which solved a few errors. The thing is compiling with the included libraries. I should be able to move on without any problems.
The working result with a few warnings:
CFLAGS=-Wall
LDLIBS=-LC:/GnuWin32/lib -lfl -lm
LSOURCES=lex.l
YSOURCES=grammar.ypp
CSOURCES=debug.cpp esta_plus.cpp heap.cpp main.cpp stjn.cpp timing.cpp tmsp.cpp token.cpp chaining.cpp exceptions.cpp constraints.cpp flexibility.cpp
HSOURCES=$(CSOURCES:.cpp=.h) includes.h
OBJECTS=$(LSOURCES:.l=.o) $(YSOURCES:.ypp=.tab.o) $(CSOURCES:.cpp=.o)
# C++ Compiler options
CXXFLAGS = -std=c++11 -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD
EXTRAFLAG = -std=c++11 -Wl,--rpath -Wl,/home/martijn/Downloads/COIN/coin-Clp/lib -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCLP_BUILD -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\"
EXTRALIB = `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --libs clp`
all: solver
solver: CFLAGS+=-g -O0 -DDEBUG
solver: $(OBJECTS) main.o debug.o
g++ $(CFLAGS) $(EXTRAFLAG) -o $# $^ $(LDLIBS) $(EXTRALIB)
solver.release: CFLAGS+=-O5
solver.release: $(OBJECTS) main.o
g++ $(CFLAGS) -o $# $^ $(LDLIBS)
main.o: main.cpp
g++ $(CXXFLAGS) -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\" `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --cflags clp` -c -o main.o `test -f 'main.cpp' || echo './'`main.cpp
flexibility.o: flexibility.cpp
g++ $(CXXFLAGS) -DSAMPLEDIR=\"`PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --variable=datadir coindatasample`\" `PKG_CONFIG_PATH=/home/martijn/Downloads/COIN/coin-Clp/lib64/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/lib/pkgconfig:/home/martijn/Downloads/COIN/coin-Clp/share/pkgconfig: pkg-config --cflags clp` -c -o flexibility.o `test -f 'flexibility.cpp' || echo './'`flexibility.cpp
%.o: %.cpp
g++ -c $(CFLAGS) -o $# $<
lex.cpp: lex.l grammar.tab.cpp grammar.tab.hpp
flex -o$# $<
%.tab.cpp %.tab.hpp: %.ypp
bison --verbose -d $<
ifneq ($(LSOURCES),)
$(LSOURCES:.l=.cpp): $(YSOURCES:.y=.tab.h)
endif
-include $(OBJECTS:.o=.d)
clean:
rm -f $(OBJECTS) $(OBJECTS:.o=.d) $(YSOURCES:.ypp=.tab.cpp) $(YSOURCES:.ypp=.tab.hpp) $(YSOURCES:.ypp=.output) $(LSOURCES:.l=.cpp) solver solver.release 2>/dev/null
.PHONY: all clean debug release

Makefile for shared library that only compiles changed files?

I am working on a project where I am creating a .so object as my output that contains several operators for use in another program. I was given a Makefile that works just fine, except it always recompiles every file whenever I run make. Originally this was not an issue, but now that there are upwards of five or more operators in the library, running make is prohibitively slow. The trouble is that for the life of me, I can't figure out how to change this Makefile into one that behaves the way I want since I've never dealt with Makefiles in this format before:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
### etc.
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
clean:
rm -f *.o *.so
The biggest issue I have is that there is only one rule (all), and I cannot find an example of a Makefile that does this or how to split it into multiple rules.
In this case, it's actually pretty straightforward. Right now, you just have an all target that's doing all the building. You need to break out the compiler invocations and link step into their own rules, and you should be off to the races:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all: plugin.cpp.o LogicalFile1.cpp.o PhysicalFile1.cpp.o LogicalFile2.cpp.o PhysicalFile2.cpp.o
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
plugin.cpp.o: plugin.cpp | test
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
LogicalFile1.cpp.o: File1/LogicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
PhysicalFile1.cpp.o: File1/PhysicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
LogicalFile2.cpp.o: File2/LogicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
PhysicalFile2.cpp.o: File2/PhysicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
test:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
clean:
rm -f *.o *.so
.PHONY: all clean test
From this point, you can simplify further, too. You could consolidate all of the compile lines into a single pattern rule, for example.
If you're willing to use the standard formats and built-in rules for make, you can write your entire makefile as easily as this:
ifeq (,$(wildcard $(IN_SOURCE_DIR)/.))
$(error Try: make IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>)
endif
OBJECTS = plugin.o LogicalFile1.o PhysicalFile1.o LogicalFile2.o PhysicalFile2.o ### etc
BOOST_LOCATION = /usr/local/boost_1_54_0
CPPFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
CXXFLAGS = -pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -Wno-system-headers -isystem -O2 -g -ggdb3
LDFLAGS = -L"$(IN_SOURCE_DIR)/lib" -L.
LDLIBS = -shared -Wl,-soname,libname.so -lm
all: libname.so
libname.so: $(OBJECTS)
$(LINK.cc) $^ $(LDLIBS) -o $#
clean:
rm -f *.o *.so
.PHONY: all clean