Makefile conditional statements not working - c

I have the following makefile code where the ifeq statement is not evaluating to true and I don't understand why not:
PROCESSOR=`uname -p`
ifeq ($(strip $(PROCESSOR)), x86_64)
PROCESSOR = -c -march=atom -fPIC -Wall -I../../inc
else
PROCESSOR = -c -march=i386 -fPIC -Wall -I../../inc
endif
I have confirmed on my system that uname -p results in "x86_64", but the ifeq statement is evaluating to false and PROCESSOR is being set to -c -march=i386 -fPIC -Wall -I../../inc. I have also tried ifeq "$(strip $(PROCESSOR))" "x86_64" and a few variations without the strip function. Anyone have any suggestions?

Backticks aren't command execution in a makefile.
Add $(info $(PROCESSOR)) above the ifeq line to see what I mean.
You want:
PROCESSOR=$(shell uname -p)
$ cat Makefile
PROCESSOR=`uname -p`
$(info backticks: $(PROCESSOR))
PROCESSOR=$(shell uname -p)
$(info $$shell: $(PROCESSOR))
$ make
backticks: `uname -p`
$shell: x86_64

Related

g++ compiled binaries give “cannot execute binary file”

I am writing CUDA code and am using the following Makefile to compile and link it together.
DEBUG = TRUE
CUDA_PATH = /usr/local/cuda
INC_DIR = ../include
ICC = -I/usr/include -I$(INC_DIR) -I$(CUDA_PATH)/include
LIB_CUDA = -L$(CUDA_PATH)/lib64
NVCC = $(CUDA_PATH)/bin/nvcc
LINT = cppcheck
LINK = $(NVCC)
CXX = g++
C_SOURCES = main.c
CUDA_SOURCES = cuda_r_lib.cu
EXE = r_lib
OBJS = main.o
CUDA_OBJS = cuda_r_lib.o
HFILES = $(INC_DIR)/r_lib.h
MAKEFILE = Makefile
REBUILDABLES = $(CUDA_OBJS) $(OBJS) r_lib
LFLAGS = -lcuda $(LIB_CUDA)
ifdef DEBUG
CFLAGS = -Wall -ggdb -pthread -fPIC -O3
CDEFINES = $(ICC)
CUDA_FLAGS = -arch=sm_20 $(ICC)
else
CFLAGS = -Wall -pthread -fPIC -O3
CDEFINES = $(ICC) -DNDEBUG=1
CUDA_FLAGS = -arch=sm_20 $(ICC)
endif
$(EXE): $(OBJS) $(CUDA_OBJS)
$(LINK) $(LFLAGS) $(OBJS) $(CUDA_OBJS) -o $(EXE)
$(OBJS): $(C_SOURCES) $(HFILES) $(MAKEFILE)
$(CXX) $(CDEFINES) $(CFLAGS) -c $(C_SOURCES) -o $#
$(CUDA_OBJS): $(CUDA_SOURCES) $(HFILES) $(MAKEFILE)
$(NVCC) $(CUDA_FLAGS) -c $(CUDA_SOURCES) -o $#
clean:
rm -f *~ $(REBUILDABLES) *ii core
lint:
$(LINT) --enable=all --inconclusive --std=posix *.c *.cu
I've got to the point where my code compiles and links cleanly. But the binary ./r_lib doesn't execute. I can't even change its permissions (tried chmod +x ...)
Here's what I get:
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ make
g++ -I/usr/include -I../include -I/usr/local/cuda/include -Wall -ggdb -pthread -fPIC -O3 -c main.c -o main.o
/usr/local/cuda/bin/nvcc -arch=sm_20 -I/usr/include -I../include -I/usr/local/cuda/include -c cuda_r_lib.cu -o cuda_r_lib.o
/usr/local/cuda/bin/nvcc -lcuda -L/usr/local/cuda/lib64 main.o cuda_r_lib.o -o r_lib
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ ll ./r_lib
-rw------- 1 rinka rinka 552223 Nov 6 19:08 ./r_lib
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ file r_lib
r_lib: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=8f2b88bf570a5d74c2c237969a93519f64636b86, not stripped
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ ./r_lib
bash: ./r_lib: Permission denied
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ chmod +x ./r_lib
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ ./r_lib
bash: ./r_lib: Permission denied
rinka#rinka-Desktop:/media/rinka/CUDA/dev/code$ ll ./r_lib
-rw------- 1 rinka rinka 552223 Nov 6 19:08 ./r_lib
I can't for the life of me figure out what I'm doing wrong - maybe I'm just tired. I looked at: gcc compiled binaries give "cannot execute binary file" but I'm not using the -c option while linking...
Also - any feedback on the compiler & linker options for nvcc that will help throw up warnings more rigorously will be very welcome. I'm not really satisfied with the warnings I got so far.
This is not a message from your compiler or build-tool, but from your shell and originates from the OS.
For the path /media/, it seems you have your files on external storage e.g. an USB-stick. That might be mounted with option noexec, so you cannot execute from there. Also, if that is VFAT, there are no permission-flags in the, so you cannot set them. Instead default flags are used by the OS and might also prevent execution a program from that partition. This is a security measure against malware.
Try mount and check options.
If I'm right, you should move the files to a normal filesystem, e.g. your home.

Appropriate Makefile to replace a gcc compile/link run?

My goal is to use a single Makefile for compiling a C app across various platforms.
I've been busily relearning C while working on a project, so as a result have not yet had the time to delve into make; instead I have a single, long gcc command in some .bat / .sh files. Needless to say that each time I change one such file, I have to make those same changes in the others. Hence, make. Conditions that need to be handled:
Builds for multiple OS & architecture, i.e. for now (at least) 32 & 64-bit for Windows & Linux, thus I need access to that info in the Makefile, and executables should go into distinct folders under /build: i.e. /win32, /win64, /lin32, /lin64 (et cetera, in future).
Required DLLs should be copied in alongside the built executable.
Separate compile & link phases (thanks #EtanReisner)
Question: Can someone show me how one would go about constructing a Makefile using the info below? And explain how each part works / why it is needed for my particular case? I have an understanding of the prerequisites approach by which Makefiles are built. Thanks in advance.
Here is my project directory tree:
+---bin
+---include
| +---enet
| +---GL
| +---libxml
| \---ncursesw
+---lib
+---src
+---fonts
\---shaders
And mingw gcc for Windows 32-bit compile:
gcc -Iinclude ./src/main.c ./src/MainCtrl.c ./src/MainView.c ./src/PerspectiveView.c ./src/LogView.c ./src/LobbyView.c ./src/TerminalView.c ./src/World.c ./src/Chunk.c ./src/CellPattern.c ./src/CellPlan.c ./src/GridPoint.c ./src/Entity.c ./src/InfluenceRadial.c ./src/AoIList.c ./src/AoI.c ./src/ChunkRenderable.c ./src/PrimitiveRenderable.c ./src/Geometry.c ./src/glew/glew.c ./src/stb/stb_image_aug.c ../curt/list_generic.c ../curt/map_generic.c ../curt/intMap.c ../curt/floatMap.c ../hedgehog/hedgehog.c ./src/Inputs.c ./src/InputResponse.c ./src/Network.c ../Disjunction/c/disjunction.c ./src/my/math/Range.c ./src/my/math/Point.c -Llib -lglfw3-32 -lopengl32 -lgdi32 -lenet-32 -lws2_32 -lwinmm -llibxml2-32 -L. -ldll32/libncursesw6 -std=c11 -m32 -w -Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -fopenmp -O0 -o ./build/win32/wa
And the gcc for Linux 64-bit compile:
gcc -Iinclude -I/usr/include/libxml2 ./src/main.c ./src/MainCtrl.c ./src/MainView.c ./src/PerspectiveView.c ./src/LogView.c ./src/LobbyView.c ./src/TerminalView.c ./src/World.c ./src/Chunk.c ./src/CellPattern.c ./src/CellPlan.c ./src/GridPoint.c ./src/Entity.c ./src/InfluenceRadial.c ./src/AoIList.c ./src/AoI.c ./src/ChunkRenderable.c ./src/PrimitiveRenderable.c ./src/Geometry.c ./src/glew/glew.c ./src/stb/stb_image_aug.c ../curt/list_generic.c ../curt/map_generic.c ../curt/intMap.c ../curt/floatMap.c ../hedgehog/hedgehog.c ./src/Inputs.c ./src/InputResponse.c ./src/Network.c ../disjunction/c/disjunction.c ./src/my/math/Range.c ./src/my/math/Point.c -Llib -L/usr/lib -l:libglfw.so.3 -lncurses -lGL -lxml2 -lenet -lm -std=c11 -m64 -w -Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -fopenmp -g -o ./wa-64.elf
(worth diffing these.)
Trial and error led tothe following... work in progress, but the basics are there. Features:
No need to manually list source / object files (all relevant sources expected to be in src)
Separate compile & link phases using shared logic for .c/.o file lists
OS & architecture autodetection (WIP), with manual override for arch (
e.g. make BITS=32)
Clean that works for both Win & *nixes
Copies in .DLLs on compile (WIP to supply a list of DLLs to copy in)
Thanks to Yanick Rochon, Samuel and Trevor Robinson for their answers, and to those who wrote the GNU Makefile examples.
CC = gcc
#Directories
HDRDIR = include
SRCDIR = ./src
OBJDIR = ./obj
BINDIR = ./bin
LIBDIR = lib
#File lists
HDRS := $(wildcard $(HDRDIR)/*.h)
SRCS := $(wildcard $(SRCDIR)/*.c)
OBJS := $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
#Autodetect OS / architecture
OS =
BITS = 32
#ifeq ($(shell echo "check_quotes"),"check_quotes")
ifeq ($(OS),Windows_NT)
OS := win
EXT := .exe
rm := del /q
cp := copy /y
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CFLAGS += -D IA32
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
OS := lin
EXT := .elf
rm := rm -f
cp := cp
CCFLAGS += -D LINUX
BITS = $(shell getconf LONG_BIT)
endif
ifeq ($(UNAME_S),Darwin)
OS := osx
EXT :=
rm := rm -f
cp := cp
CCFLAGS += -D OSX
BITS = $(shell getconf LONG_BIT)
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CCFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CCFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CCFLAGS += -D ARM
endif
endif
#Define flags for compile & link
CFLAGS = -I$(HDRDIR) -std=c11 -m64 -fopenmp -Wall -Werror -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -w -O0 -DGLEW_STATIC
LFLAGS = -L$(LIBDIR)
#Do we want verbose linker messages?
LVERBOSE := false
LLIBS =
ifeq ($(OS),win)
LLIBS += -lglfw3-$(BITS) -lglew32s -lglew32 -lopengl32 -lgdi32 -lwinmm
endif
ifeq ($(OS),lin)
LLIBS += -lglew32s -lglew32 -lGL -lm
endif
ifeq ($(LVERBOSE),true)
LFLAGS += -Wl,--verbose
endif
TARGET = program$(EXT)
#Rules
$(BINDIR)/$(TARGET): $(OBJS)
#$(CC) -o ./$# $(OBJS) $(LFLAGS) $(LLIBS)
#echo Linking complete.
#$(cp) $(LIBDIR)\glfw3.dll $(BINDIR)
#echo DLLs accompanying executable.
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o ./$#
#echo Compiled $<.
.PHONEY: clean
clean:
ifeq ($(OS),win)
#$(rm) $(subst /,\\,$(OBJS))
#$(rm) $(subst /,\\,$(BINDIR)/*.*)
else
#$(rm) $(OBJS)
#$(rm) $(BINDIR)/*
endif
#echo Cleanup complete.
#$(subst /,\\, $(SOMETHING)) replaces all (make-native) forward slashes with backslashes, for Windows.

makefile - how to exclude file extension suffix from a variable

the next makefile receive the file to compile from its command line arg -ARGS. For example
make ARGS="out.c"
I would like to replace the name of the created executable "run" with the variable ARGS excluding the suffix
in this example : run="out"
all: Task1
Task1: outputs/output.o
gcc -g -m32 -Wall -o run outputs/output.o
outputs/output.o: outputs/${ARGS}
gcc -m32 -g -w -Wall -ansi -c -o outputs/output.o outputs/${ARGS}
.PHONY: clean
run: clean Task1
clean:
rm -f outputs\output.o Task1
The crude way to do what you ask is simply:
EXEC := $(basename $(ARGS))
all: Task1
Task1: outputs/output.o
gcc -g -m32 -Wall -o $(EXEC) outputs/output.o
A better way is:
EXEC := $(basename $(ARGS))
all: $(EXEC)
$(EXEC): outputs/output.o
gcc -g -m32 -Wall -o $(EXEC) outputs/output.o
Better still:
EXEC := $(basename $(ARGS))
all: $(EXEC)
$(EXEC): outputs/output.o
gcc -g -m32 -Wall -o $# $^
If using GNU make you need the basename function, perhaps as $(basename $(AUX)). Maybe variables like $(*F) might be useful too (please read the documentation). However, your Makefile is probably wrong.
I can't suggest an improvement, because what you want to do and to happen is unclear.
BTW, use remake (as remake -x) or at least make --trace (with a recent enough GNU make 4.x) to understand what make is doing and why.
Also, you'll find several examples of Makefile-s: here & there
etc... Don't forget that make has a many builtin rules, you'll get them by running make -p
You won't lose your time by reading the documentation of GNU make, and some tutorials, and some examples of Makefile-s.

How do I add a debug option to Makefile

I've got the below simple Makefile which I use for compiling a C program:
all:
gcc -Wall -o myfile myfile.c lol_dht22/dht22.c lol_dht22/locking.c -lwiringPi -lcurl -lm
I want to add in a debug option so I can compile with -DDEBUG, so if I run
make
it compiles as normal. and if I run
make debug
it compliles with the debug flag.
I have read through a few tutorial but seems to be getting more and more confused.
If you want to know how to do it well, here it is. You don't do make debug, instead, you should call
>make
or
>make DEFS=DEBUG
or
>make DEFS='ANY DEFINES YOU WANT'
In addition to normal Make rebuild criteria, the following Makefile recognizes rebuilds based on DEFS.
define DEPENDABLE_VAR
.PHONY: phony
$1: phony
#if [[ `cat $1 2>&1` != '$($1)' ]]; then \
echo -n $($1) > $1 ; \
fi
endef
$(eval $(call DEPENDABLE_VAR,DEFS))
.PHONY: all
all: myfile
SRCS := myfile.c lol_dht22/dht22.c lol_dht22/locking.c
myfile: $(SRCS) Makefile DEFS
gcc $(addprefix -D, $(DEFS)) -Wall -o $# $(SRCS) -lwiringPi -lcurl -lm
Here's an example makefile that has the two options you are looking for.
all:
gcc -Wall -o myfile myfile.c lol_dht22/dht22.c lol_dht22/locking.c -lwiringPi -lcurl -lm
debug:
gcc -DDEBUG -Wall -o myfile myfile.c lol_dht22/dht22.c lol_dht22/locking.c -lwiringPi -lcurl -lm
You just needed to add a debug option, which is done in similar fashion to the 'all' option you had already declared.

Is it possible to compile svdlibc on a mac (64 bit)?

I'm trying to compile svdlibc on a 64 bit mac. Running the make file returns the error message:
main.c:1: error: CPU you selected does not support x86-64 instruction set
main.c:1: error: CPU you selected does not support x86-64 instruction set
make: *** [main.o] Error 1
Which doesn't make much sense.
The make file is:
# Linux or Windows:
CC = gcc -Wall -O4 -march=i486
# CC = icc -w1 -O3 -march=i486
# Macintosh:
ifeq ($(HOSTTYPE),powerpc)
CC = cc -pipe -O3 -Wall -fno-common -arch ppc
endif
LIBS=-lm
OBJ=svdlib.o svdutil.o las2.o
svd: Makefile main.o libsvd.a
${CC} ${CFLAGS} -o svd main.o libsvd.a ${LIBS}
mv -f $# ${HOSTTYPE}/$#
ln -s ${HOSTTYPE}/$# $#
main.o: Makefile main.c svdlib.h
${CC} ${CFLAGS} -c main.c
libsvd.a: ${HOSTTYPE} ${OBJ}
rm -f $# ${HOSTTYPE}/$#
ar cr $# ${OBJ}
ranlib $#
mv -f $# ${HOSTTYPE}/$#
ln -s ${HOSTTYPE}/$# $#
svdlib.o: Makefile svdlib.h svdlib.c
${CC} ${CFLAGS} -c svdlib.c
svdutil.o: Makefile svdutil.c svdutil.h
${CC} ${CFLAGS} -c svdutil.c
las2.o: Makefile las2.c svdlib.h svdutil.h
${CC} ${CFLAGS} -c las2.c
clean:
rm *.o
$(HOSTTYPE):
if test ! -d $(HOSTTYPE); \
then mkdir $(HOSTTYPE); fi
Editing the make file to alter the -march flag lets the compilation proceed but apparently the linking fails with:
ld: lto: could not merge in main.o because Invalid ALLOCA record for
architecture x86_64
Has anyone done this? Or is there a different svd library that I should use instead? (For large sparse matrices?)
EDIT: porneL seems to have found the problem. Changing the top line in the makefile to:
CC = gcc -Wall -O3 -march=x86-64
compilation work. Haven't tested the results yet, but looks very promising.
-O4 causes this for some reason. Use -O3 instead.
You could try with port ( http://www.macports.org/ ) it seems it s availablee :
svdlibc #1.34 (math, science)
SVDLIBC is a C library to perform singular value decomposition
Basically you ll install macports then , sudo port install svdlibc.

Resources