I have a problem with GDB in Archlinux:
Even I add -g in my Makefile gdb say (no debugging symbols found)...done..
But if I compile manually gcc -g *.c it work...
I don't know what is don't work in my Makefile ?
My Archlinux:
Linux sime_arch 4.13.4-1-ARCH #1 SMP PREEMPT Thu Sep 28 08:39:52 CEST 2017 x86_64 GNU/Linux
My GCC:
gcc version 7.2.0 (GCC)
My Makefile:
SRC = test.c \
test2.c
OBJ = $(SRC:.c=.o)
NAME = test_name
CFLAG = -Wall -Werror -Wextra
all: $(NAME)
$(NAME): $(OBJ)
gcc -g $(OBJ) -o $(NAME) $(CFLAG)
clean:
rm -f $(OBJ)
fclean: clean
rm -f $(NAME)
re: fclean all}
Thanks in advance
You are adding the -g only to the linking command. The object files are generated by the auto compile target of make. This doesn't have the -g flag in it.
You have 2 options -
Change your variable CFLAG to CFLAGS and add -g to it. CFLAGS is picked by the auto compile command and it will create object files with debug info
Add the following target -
%.o: %.c
gcc -g $(CFLAG) -o $# $<
before the $(NAME) target.
The second one gives you more control with the targets but the first method is the standard way of compiling.
Also, always try using standard names for variables unless you specifically need to name them separately.
Related
A little background for the problem I am having:
I just migrated from Ubuntu Focal Fossa to Mint Cinnamon keeping my home in a partition
libbsd is installed and can be used to compile some test code (I did a "Hello world" test using strlcpy in the main to verify that libbsd was usable)
Basically in order to use this project I have to use a library provided by my school (which compiled without problems in my last system) which is has a testing script that is going to run a test with its own Makefile:
INC=%%%%
INCLIB=$(INC)/../lib
UNAME := $(shell uname)
CFLAGS= -I$(INC) -O3 -I.. -g
NAME= mlx-test
SRC = main.c
OBJ = $(SRC:%.c=%.o)
LFLAGS = -L.. -lmlx -L$(INCLIB) -lXext -lX11 -lm
ifeq ($(UNAME), Darwin)
# mac
CC = clang
else ifeq ($(UNAME), FreeBSD)
# FreeBSD
CC = clang
else
#Linux and others...
CC = gcc
LFLAGS += -lbsd
endif
all: $(NAME)
$(NAME): $(OBJ)
$(CC) -o $(NAME) $(OBJ) $(LFLAGS)
clean:
rm -f $(NAME) $(OBJ) *~ core *.core
re: clean all
mlx would be the name of the library. For who is not familiar with this syntax (I was not) INC=%%%% is going to expand to /usr/include.
The command to compile the test binary expands to:
$ gcc -o mlx-test main.o -L.. -lmlx -L/usr/include/../lib -lXext -lX11 -lm -lbsd
which generates the error
/usr/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/bin/ld: cannot find -lbsd
(that path expands to usr/x86_64-unknown-linux-gnu/bin/ld)
Now, this kinda looks like a gcc configuration, in fact I saw something similar in the output of the command gcc --version -v, but only with x86_64-linux-gnu so without the "unkown" part. Also, one of the weird things is that the path that appears in the error actually does not exist in my system.
I already tried reinstalling gcc but with no different result.
I hope the description was clear enough, please let me know if you may need any other detail that I did not think of.
So I have two C files which are master.c, slave.c and then config.h and I'm trying to build a makefile for the execution of these files and I'm getting an error.
I'm using a normal terminal on MacOS and when executing make I get the following error:
ss#US3FHIM0XQ86TJG: ~/project-2[master*]$ make
gcc -o master config.h master.c -g -I -std=gnu99
clang: error: cannot specify -o when generating multiple output files
make: *** [master] Error 1
Here is what my makefile looks like:
CC = gcc
CFLAGS = -g -I -std=gnu99
all: master slave
master: config.h master.c
$(CC) -o $# $^ $(CFLAGS)
slave: config.h slave.c
$(CC) -o $# $^ $(CFLAGS)
clean:
rm master slave cstest logfile.*
Can someone spot what might be causing this issue?
Remove config.h. You can compile it on the command line and omit "config.h", ie:
gcc -o master master.c -g -I -std=gnu99
Some people like to put that -o at the end:
gcc -g -I -std=gnu99 -c master.c -o master
A more appropriate way would be:
gcc -g -I/usr/include -std=gnu99 -c master.c -o master
Generally, the -I has a path, such as -I/usr/include, but you can omit the -I as your compiler usually looks there first.
Also, you may have to tweak your Makefile and omit the config.h if it is happening when you type make.
Some little errors you can fix by compiling the object by hand (ie, as above, gcc -g -I/usr/include -std=gnu99 -c master.c -o master)
Once you edit Makefile and remove config.h, and perhaps use -I/usr/include or path to your headers, you can run:
make clean
make all
or just:
make slave
or:
make master
etc, etc
$^ is a placeholder for the list of dependencies. That is why the rule
master: config.h master.c
$(CC) -o $# $^ $(CFLAGS)
runs the command
gcc -o master config.h master.c -g -I -std=gnu99
Compiling .h produces one output, compiling .c produces another output. The compiler does not know to which of them to apply -o. The proper way is using rules
master: master.c config.h
$(CC) -o $# $< $(CFLAGS)
slave: slave.c config.h
$(CC) -o $# $< $(CFLAGS)
$< is a placeholder for the first item in the list of dependencies. These rules run gcc properly
gcc -o master master.c -g -I -std=gnu99
gcc -o slave slave.c -g -I -std=gnu99
I have problem with linking libevent into my c project on ubuntu 14.04 LTS Server. Everything works fine on ArchLinux and Centos7 (both ubuntu and centos I run on virtual machine).
These is my Makefile:
TARGET: opoznienia
CFLAGS = -Wall -O2 --std=c11 -D DEBUG=1 $(shell pkg-config --cflags libevent_pthreads) -pthread -Wextra
LFLAGS = -Wall $(shell pkg-config --libs libevent_pthreads) -pthread -Wextra
OFILES = main.o err.o dropnobody.o ... <-- tl;tr
opoznienia: $(OFILES)
$(CC) $(LFLAGS) $^ -o $#
.PHONY: clean TARGET
clean:
rm -f opoznienia *.o *~ *.bak
On ubuntu I get error:
telnet_server.c:(.text+0xfc): undefined reference to `event_new'
GNU linker parses the object files arguments (.o .a .so) from left to right trying to match all the undefined symbols. And the order of object files is really important here, because GNU linker 'forgets' any symbols if they were not used by any object file passed in the argument list before the current object file.
In your case try changing the linkage order form:
$(CC) $(LFLAGS) $^ -o $#
To:
$(CC) $^ $(LFLAGS) -o $#
Let us know if this helps.
When I do practice , I have a practice path.
Under this path , I have an Include path named myInclude (I have some useful function is this folder and I always use it.)
And a code path named symbol_try.I always make add new folder (with a c file and main function in it) in symbol_try and compile it.
Each time I have to compile it by gcc in terminal .Its a boring work , so I write a Makefile.
Here is an example:
the main Makefile in practice path:
FOBJS=
include myInclude/Rule.mk
include symbol_try/codeList_13.1/Rule.mk
symbol:$(FOBJS) <==What exactly I what . A executable file.
gcc -o symbol $(FOBJS) -pthread -lpthread
subsystem:
cd myInclude/ && $(MAKE)
cd symbol_try/codeList_13.1/ &&$(MAKE)
clean:
rm -rf symbol
In the myInclude/Rule.mk
FOBJS+=myInclude/otherFunction.o myInclude/error.o \
myInclude/unit.o myInclude/unitTest.o\
In the symbol_try/codeList_13.1/Rule.mk
FOBJS+=symbol_try/codeList_13.1/codeList_13.1.o
In myInclude/Makefile:
OBJS=otherFunction.o error.o unit.o unitTest.o
ALL:$(OBJS)
.PHONY:ALL
$(OBJS):%.o:%.c
gcc -c $< -o $#
clean :
otherFunction.o error.o unit.o
In symbol_try/codeList_13.1/Makefile:
codeList_13.1.o:codeList_13.1.c
gcc -c codeList_13.1.c
Well.That can work. But as you see , I have to write a Rule.mk(to initialize the FOBJS) and a Makefile for each folder.
I am new for make , I want find a way more concise , witch I only need write one Makefile for each folder and a main Makefile.No Rule.mk any more.
PS: I always change the code in myInclude ,so I don't want to build it a library.
Thanks for any help.
Here's one way you can do it with just one Makefile:
CC = gcc
CPPFLAGS += -I myInclude/ (1)
CFLAGS += -std=c99 -Wall (2)
VPATH = myInclude/ \ (3)
symbol_try/codeList_13.1/
symbol: otherFunction.o error.o unit.o unitTest.o codeList_13.1.o (4)
$(CC) -o $# $^ (5)
.PHONY : clean
clean:
rm -f symbol *.o
Note that make knows how to build C files and has some standard macros: CC, CPPFLGAS, CFLAGS
Add the include paths of your headers. You presumably have some headers for the individual object files in the myInclude directory.
Put the compiler flags here.
Add the paths to the source files you want to build.
List the object files that the executable depends upon
As there is no file called symbol.c you need to tell make how to create symbol.o with a rule. $# means the target ('symbol', here), and $^ means all of the prerequisites (the object files listed).
Here's a list of all of the files in my test directories for this:
$ find . -type f
.
./Makefile
./myInclude/error.c
./myInclude/header.h
./myInclude/otherFunction.c
./myInclude/unit.c
./myInclude/unitTest.c
./symbol_try/codeList_13.1/codeList_13.1.c
And the build output:
$ make
gcc -std=c99 -Wall -I myInclude/ -c -o otherFunction.o myInclude/otherFunction.c
gcc -std=c99 -Wall -I myInclude/ -c -o error.o myInclude/error.c
gcc -std=c99 -Wall -I myInclude/ -c -o unit.o myInclude/unit.c
gcc -std=c99 -Wall -I myInclude/ -c -o unitTest.o myInclude/unitTest.c
gcc -std=c99 -Wall -I myInclude/ -c -o codeList_13.1.o symbol_try/codeList_13.1/codeList_13.1.c
gcc -o symbol otherFunction.o error.o unit.o unitTest.o codeList_13.1.o
Why don't you create a library from the objects in myInclude and do the linking in the Makefile in your code path (symbol_try/codeList_13.1). The latter is better anyway because the needed libraries (-pthread -lpthread in your case) might change as well for some other code.
The main Makefile now would have got nothing to do but call make in all needed subdirectories.
In each folder have a makefile with
SOURCES=sample.c sampletest.c
OBJECTS=$(SOURCES:%.c=$(OBJDIR)/%.o)
all: $(OBJECTS)
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -o $# $<
In the root directory of a project, create a makefile with a rule to compile every sub-folder like the below.
Dirs= path-to-rootdir
objs:
set -e ; \
for i in $(Dirs) ; do \
$(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS_MODULE)" LDFLAGS="$(LDFLAGS)" OBJDIR="$(OBJDIR)" -C $$i; \
done
And then you could use it build the executable by adding a rule
EXE: objs
$(CC) -L./Path1 $(LIB_PATH) -llib1 -o $(EXE_NAME) $(wildcard $(OBJDIR)/*.o)
Hope this helps!!!
I am trying to write a makefile which uses macros to create multiple executables from multiple files at once. I tried searching through previously answered questions but, because I am fairly new to programming in C as well as working with gcc, I was not able to find an answer to my question.
Here is what I have so far:
CC=gcc
CFLAGS=-I.
OBJ = ex1.c ex3.c
EXECUTABLE = ex1 ex3
$(EXECUTABLE): $(OBJ)
gcc -o $# $^ $(CFLAGS)
clean:
rm -f $(EXECUTABLE)
I would like the line
$(EXECUTABLE): $(OBJ)
to create executables ex1 and ex3 from files ex1.c ex3.c respectively.
For this particular case, where each executable has a single source file with .c extension, all you need is a one line Makefile:
all: ex1 ex3
The built-in default rules for make then work already:
$ make
cc -O2 -pipe ex1.c -o ex1
cc -O2 -pipe ex3.c -o ex3
Behind the scene, make is using the POSIXly mandated built-in single suffix rule
.c:
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $<
Vary the command to your liking with make CC=gcc CFLAGS=-O2 LDFLAGS=-s and similar.
Trivia of the day: in fact, if you are willing to name the targets when invoking make, you can use an empty or even run without any Makefile:
$ make -f /dev/null CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c -o ex1
gcc -O2 -s ex3.c -o ex3
$ rm -f Makefile ex1 ex3
$ make CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c -o ex1
gcc -O2 -s ex3.c -o ex3
Make magic!
As a rule of thumb, don't reinvent the wheel (or rules), use the rules that are already there. It simplifies your and make's life a lot. This makes for small and sexy makefiles to impress the ladies with :-)
Some suggestions (assuming you use GNU make, not something else)
First, run once make -p, you'll understand what builtin rules make is knowing. Look in particular for COMPILE.c and LINK.c
Then, I suggest
CFLAGS= -g -Wall -I.
(because you really want -g for debugging, and -Wall to get most warnings)
And you probably don't need
$(EXECUTABLE): $(OBJ)
gcc -o $# $^ $(CFLAGS)
However, I suggest adding before most other rules
.PHONY: all clean
all: $(EXECUTABLES)
Actually, I would code your Makefile (for GNU make!) as follow
# file Makefile
CC= gcc
RM= rm -vf
CFLAGS= -Wall -g
CPPFLAGS= -I.
SRCFILES= ex1.c ex2.c ## or perhaps $(wildcard *.c)
OBJFILES= $(patsubst %.c, %.o, $(SRCFILES))
PROGFILES= $(patsubst %.c, %, $(SRCFILES))
.PHONY: all clean
all: $(PROGFILES)
clean:
$(RM) $(OBJFILES) $(PROGFILES) *~
## eof Makefile
Remember that tab is a significant character in Makefile-s (action part of rules). In this answer, lines starting with four spaces at least should really start with a tab character.
Once everything is debugged consider running make clean to clean everything, and then make -j CFLAGS=-O2 all to compile in parallel everything with optimizations.
At last, I recommend using remake and running remake -x to debug complex Makefile-s
Of course, I'm supposing that your directory has only single-file programs.
BTW, there are other build automation tools. Perhaps you might consider using omake or ninja. For building large programs (millions of source code lines) consider also automake, ccache, cmake, icecream. In some cases, consider generating some C code with GPP, GNU bison, SWIG, etc... or using your own Python or Guile script (or C meta-program). See also this draft report.
Don't forget to use a version control system like git for your source files. It is also time to learn such a tool.
The following answer includes multiple executable such as initiate, process1, process2, ..., process4.
LOCAL_INCLUDE=./
all: clean process_first process_second init
process_first:
gcc -g -o process1 -I$(LOCAL_INCLUDE) process1.c -lzmq -L. -L./.
gcc -g -o process2 -I$(LOCAL_INCLUDE) process2.c -lzmq -L. -L./.
process_second:
gcc -g -o process3 -I$(LOCAL_INCLUDE) process3.c -lzmq -L. -L./.
gcc -g -o process4 -I$(LOCAL_INCLUDE) process4.c -lzmq -L. -L./.
init:
gcc -g -o initiate -I$(LOCAL_INCLUDE) initiate.c -lzmq -lconfig -lpthread -L. -L./. -ldl -lrt
clean:
rm -rf init_manager.o init_manager
rm -rf process1 process2 process3 process4
NOTE: It is a good practice to clean and touch all the executable files before making them again.
You're close, but you need a pattern rule:
$(EXECUTABLE): % : %.c
And then a default rule to make it build both:
all: $(EXECUTABLE)