Makefile two variants of one executable dependent on make run - makefile

I am having a lot of trouble with figuring out how to make it so that I can make two executables for client dependent on how I run make. When running just "make" I want client to be like so:
client: client.o open.o close.o
gcc -g -o client client.o open.o close.o
and then when I run "make normal" I want client to be like this:
client: client.o
gcc -g -o client client.o
I just have no idea how to go about doing this, I have been at this for a while and haven't found anything that is simple and helpful. The entire makefile is below to put it all in context.
all: client host tstWrappers
client: client.o open.o close.o
gcc -g -o client client.o open.o close.o
client.o: client.c
gcc -g -c client.c
host: host.o
gcc -g -o host host.o
host.o: host.c
gcc -g -c host.c
tstWrappers: tstWrappers.o open.o close.o
gcc -g -o tstWrappers tstWrappers.o open.o close.o
tstWrappers.o: tstWrappers.c
gcc -g -c tstWrappers.c
open.o: open.c
gcc -g -c open.c
close.o: close.c
gcc -g -c close.c
clean:
rm -f client host client.o host.o tstWrappers tstWrappers.o open.o close.o

The simplest thing to do here is likely just to duplicate the target:
client: client.o open.o close.o
gcc -g -o $# $^
client-normal: client.o
gcc -g -o $# $^
and then run make client-normal to generate a client-normal binary.
(Notice that I replaced the manually listed output and input files with the appropriate Automatic Variables to avoid duplication.)
If you wanted to use make and make MODE=normal (or similar) then you could do this instead:
ifneq (normal,$(MODE))
EXTRA_OBJECTS := open.o close.o
endif
client: client.o $(EXTRA_OBJECTS)
gcc -g -o $# $^

Related

How to generate debug information in gcc/clang with separated compilation/link process in Makefile (-c -g)?

I had made a Makefile from Hilton Lipschitz's blog, and made little changes to it in order to generate debug information. Main parts are listed:
CC := clang -arch x86_64
CFLAGS := -c -O0
$(TARGET): $(OBJECTS)
#echo " Linking $(TARGET)"; $(CC) $^ -o $(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDLIST)
#echo "Compiling $<..."; $(CC) $(CFLAGS) $(INC) -o $# $<
debug: CFLAGS += -g
debug: $(TARGET)
Now make runs these commands (paths are summarized with ...):
clang -arch x86_64 -c -O0 -I... -o build/program.o src/program.c
clang -arch x86_64 build/program.o -o bin/program -L...
While make debug runs these commands:
clang -arch x86_64 -c -O0 -g -I... -o build/program.o src/program.c
clang -arch x86_64 build/program.o -o bin/program -L...
The problem is when I execute make or make debug, no program.dSYM subfolder will be made in bin folder. Instead, when I compile without -c argument:
clang -arch x86_64 -g -O0 -I... -L... -o bin/program.o src/program.c
both executable file and .dSYM are created in bin folder.
How can I add debugging information generation feature to this Makefile while separating compiling and linking process?
In which step (compiling/linking) debug information is produced?
UPDATE: I created a GitHub repo and uploaded related Makefile and source to it. To reproduce the problem, please run these commands in your terminal:
git clone https://github.com/hamid914/gdb-lldb-test.git
cd gdb-lldb-test
make debug
The last line, make debug executes these commands:
clang -arch x86_64 -c -O0 -std=c11 -g -I include -I include/libs -I /usr/local/include -o build/program.o src/program.c
clang -arch x86_64 build/program.o -o bin/program -L /usr/local/lib -lm -g
And content of bin folder is:
$ ls bin
program
While if I run clang without -c argument:
clang -arch x86_64 -O0 -std=c11 -g -I include -I include/libs -I /usr/local/include -L /usr/local/lib -lm -o bin/program src/program.c
Contents of bin folder are:
$ ls bin
program program.dSYM
You need to add -g to the linker recipe as well in order to generate .dSYM files, the standard way would be to add
debug: LDFLAGS += -g
but the example you're following defines its own variables for no good reason, it looks like LIB should work however.

Why does make delete my temporary files?

I have a simple Makefile,
.PHONY: clean
PROGRAMS=$(patsubst main%.cpp,example%,$(wildcard main*.cpp))
all: ${PROGRAMS}
GCCVERSION=$(shell gcc -dumpversion)
GLCFLAGS=$(shell pkg-config --cflags gl)
CPPFLAGS=-Wall -O2 ${GLCFLAGS}
ifeq "${GCCVERSION}" "4.5.2"
CXXFLAGS=-std=c++0x
else
CXXFLAGS=-std=c++11
endif
GLLIBS=$(shell pkg-config --libs gl)
LIBS=${GLLIBS} -lglut
example%: main%.o shaders.o fileutils.o
${CXX} $^ ${LIBS} -o $#
clean:
rm -f *.o ${PROGRAMS}
But when I executed it, it delete the *.o files as last command. I don't know why:
$ make
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o main01.o main01.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o shaders.o shaders.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o fileutils.o fileutils.cpp
g++ main01.o shaders.o fileutils.o -lGL -lglut -o example01
rm main01.o fileutils.o shaders.o
Is there anything wrong with my Makefile?
Intermediate files are deleted by design: see Chained Rules in GNU make manual.
Use .SECONDARY or .PRECIOUS targets to keep your precioussss temp files.
Just to clarify the previous response, you need to add a special rule like
.PRECIOUS: myfile.o

Ubuntu LDFLAGS --as-needed

I have a C project that won't link correctly, and I suspect it's because of the --as-needed flag passed to the ld program by gcc. Because of that flag, gcc sees any linked library listed as an option before the *.c files as unnecessary, and won't link them.
PREFIX?=/usr/local
CFLAGS=-D_LARGEFILE64_SOURCE=1 -g -Wall -I${PREFIX}/apr/include/apr-1 -I${PREFIX}/apr/include/apr-util-1
LDFLAGS=-lapr-1 -pthread -laprutil-1
all: devpkg
devpkg: bstrlib.o db.o shell.o commands.o
install: all
install -d $(DESTDIR)/$(PREFIX)/bin/
install devpkg $(DESTDIR)/$(PREFIX)/bin/
clean:
rm -f *.o
rm -f devpkg
rm -rf *.dSYM
When I run this makefile I get the following.
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o bstrlib.o bstrlib.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o db.o db.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o shell.o shell.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o commands.o commands.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -lapr-1 -pthread -laprutil-1 devpkg.c bstrlib.o db.o shell.o commands.o -o devpkg
/tmp/ccZcAm9b.o: In function `main':
/home/zach/Desktop/devpkgzed/devpkg.c:14: undefined reference to `apr_pool_initialize'
/home/zach/Desktop/devpkgzed/devpkg.c:15: undefined reference to `apr_pool_create_ex'
/home/zach/Desktop/devpkgzed/devpkg.c:29: undefined reference to `apr_getopt_init'
/home/zach/Desktop/devpkgzed/devpkg.c:31: undefined reference to `apr_getopt'
My issue is that I don't really understand how make is coming up with these commands via the CFLAGS that are set. How can I get the linker options to follow the compilation part instead of the other way around, which is triggering this issue?
Make has built-in rules to compile source files and link executables and libraries. The commands you list are produced by these rules.
The reason this fails for you is that, when linking, libraries should be listed after object files, because the linker does a single pass through its arguments and will discard any symbols that are not unresolved at the time they are seen. To correct it, put your libraries in the LDLIBS variable, not the LDFLAGS variable (i.e. just replace LDFLAGS by LDLIBS). The LDFLAGS variable is meant for non-library options for the linker, such as -L or -shared etc

Programming in Lua on OS X?

What can I use to program Lua script on Mac OS X? I'm looking for something that I can use to compile/interpret Lua script on OS X.
My preferred way:
brew install lua
Thanks, Max!
And if you need to know how to install Homebrew, see Link and:
/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"
The Lua source easily compiles with no changes on the mac. It will build lua (the interpreter which can act on a source script, a pre-compiled script or interactively) and luac which can be used to pre-compile source scripts.
From the lua.org website: http://luabinaries.luaforge.net/download.html. The ones you want are the darwin binaries (they say Mac OS X in the description).
My favorite way (from the shell):
sudo port install lua
I LOVE macports!
Here is my terminal session from compiling and installing Lua from source, basically following these directions. I already had Apple's Developer Tools installed, and /usr/local/bin was already in my PATH, so I was able to skip some of the more time-consuming and/or tedious steps in the directions.
$ cd ~/Downloads
$ tar -xf lua-5.1.4.tar
$ cd lua-5.1.4
$ make macosx
cd src && make macosx
make all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline"
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lapi.o lapi.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lcode.o lcode.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ldebug.o ldebug.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ldo.o ldo.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ldump.o ldump.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lfunc.o lfunc.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lgc.o lgc.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o llex.o llex.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lmem.o lmem.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lobject.o lobject.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lopcodes.o lopcodes.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lparser.o lparser.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lstate.o lstate.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lstring.o lstring.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ltable.o ltable.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ltm.o ltm.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lundump.o lundump.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lvm.o lvm.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lzio.o lzio.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lauxlib.o lauxlib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lbaselib.o lbaselib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ldblib.o ldblib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o liolib.o liolib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lmathlib.o lmathlib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o loslib.o loslib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o ltablib.o ltablib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lstrlib.o lstrlib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o loadlib.o loadlib.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o linit.o linit.c
ar rcu liblua.a lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o loadlib.o linit.o
ranlib liblua.a
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lua.o lua.c
gcc -o lua lua.o liblua.a -lm -lreadline
gcc -O2 -Wall -DLUA_USE_LINUX -c -o luac.o luac.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o print.o print.c
gcc -o luac luac.o print.o liblua.a -lm -lreadline
$ make test
src/lua test/hello.lua
Hello world, from Lua 5.1!
$ sudo make install INSTALL_TOP=/usr/local
Password:
cd src && mkdir -p /usr/local/bin /usr/local/include /usr/local/lib /usr/local/man/man1 /usr/local/share/lua/5.1 /usr/local/lib/lua/5.1
cd src && install -p -m 0755 lua luac /usr/local/bin
cd src && install -p -m 0644 lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp /usr/local/include
cd src && install -p -m 0644 liblua.a /usr/local/lib
cd doc && install -p -m 0644 lua.1 luac.1 /usr/local/man/man1
$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print "Hi"
Hi
> = 2 + 3
5
> ^c
$ cd test
$ lua factorial.lua
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000
16! = 20922789888000
If you don't want to compile your own Lua binaries, you can try ZeroBrane Studio Lua IDE, which comes packaged as a .dmg file for OSX. It's an IDE that allows you to edit and debug your Lua scripts. If you are just starting with Lua, it also includes 50+ examples and demo scripts, as well as integrated instructions on running them, so you won't be facing an empty screen not knowing where to start.
I just recently found Rudix—a maintained collection of precompiled Unix software for Mac.
While I'm sure you've already figured out a way of installing Lua, I came across your question by Googling the same thing. For anyone that's interested, here's the link to a recent Lua 5.1.4 dmg.

How should a very simple Makefile look like for Cuda compiling under linux

I want to compile a very basic hello world level Cuda program under Linux. I have three files:
the kernel: helloWorld.cu
main method: helloWorld.cpp
common header: helloWorld.h
Could you write me a simple Makefile to compile this with nvcc and g++?
Thanks,
Gabor
I've never heard of Cuda before, but from the online documentation it looks as if X.cu is supposed to be compiled into X.o, so having helloWorld.cu and helloWorld.cpp is not a good idea. With your permission I'll rename the "kernel" helloKernel.cu, then this should work:
NVCC = nvcc
helloWorld.o: helloWorld.cpp helloWorld.h
$(NVCC) -c %&lt -o $#
helloKernel.o: helloKernel.cu
$(NVCC) -c %&lt -o $#
helloWorld: helloWorld.o helloKernel.o
$(NVCC) %^ -o $#
(Note that those leading spaces are tabs.)
If that works, try a slicker version:
NVCC = nvcc
helloWorld.o: %.o : %.cpp %.h
helloKernel.o: %.o : %.cu
%.o:
$(NVCC) -c %&lt -o $#
helloWorld: helloWorld.o helloKernel.o
$(NVCC) %^ -o $#
Just in case, here's my variant. I use it to compile CUDA projects on Mac, but I think it will suit Linux too. It requires CUDA SDK.
BINDIR = ./ # places compiled binary in current directory
EXECUTABLE := helloWorld
CCFILES := helloWorld.cpp
CUFILES := helloWorld.cu
# an ugly part - setting rootdir for CUDA SDK makefile
# look for common.mk - I don't know where SDK installs it on Linux -
# and change ROOTDIR accordingly
ROOTDIR := /Developer/GPU\ Computing/C/common
include $(ROOTDIR)/../common/common.mk
My version, verbose but transparent:
myapp: myapp.o
g++ -fPIC -o $# $< -L /usr/local/cuda/lib -lcudart
myapp.o: myapp.cu
/usr/local/cuda/bin/nvcc --compiler-options -fno-strict-aliasing \
-I/usr/local/cuda/include \
-DUNIX -O2 -o $# -c $<
matrixMul: matrixMul.o
g++ -fPIC -o $# $< -L /usr/local/cuda/lib -lcudart
# It MUST be named .cu or nvcc compiles as regular C !!! (no __global__)
matrixMul.o: matrixMul.cu
/usr/local/cuda/bin/nvcc --compiler-options -fno-strict-aliasing \
-I/usr/local/cuda/include \
-DUNIX -O2 -o $# -c $<
Here is an example what my current project looks like. As you can see there is a few OpenGL libraries
ce : cudaExample.c cudaExample.h
cp cudaExample.c cudaExample.cu
/usr/local/cuda/bin/nvcc -arch=sm_20 -o ce -lglut -lGL -lGLU -lXext -lXmu -lX11 -lm cudaExample.cu
then run make ce
and ./ce

Resources