C gcc compilation question and makefiles - c

Not even quite sure what my question is. The short of it is, for a class I'm supposed to add some functionality to this c file, and it came with a handy makefile.
CFLAGS=-DUNIX -lreadline -lcurses -ansi -pedantic-errors
DEBUG=-g
#DEBUG=
all: shell
shell: shell.c parse.c parse.h
gcc $(CFLAGS) $(DEBUG) shell.c parse.c -o shell
clean:
rm -f shell *~
I have to add features to shell.c. I'm very new to C (usually use c++ or c#) so I'm testing out little things in a separate little tests.c file. Things like, see what exactly certain system calls return, how to printf them right, etc. Anyway, tests.c seems to be conforming to different c compiler standards or I'm compiling it wrong. If I accidentally use // to comment something out or declare a variable somewhere other than at the start in shell.c, the compiler yells at me. It doesn't care in tests.c.
I compile tests.c with "gcc tests.c -o tests"
If I compile the shell using "gcc shell.c parse.c -o shell" it compiles fine, but running it simply gives me a segmentation fault. I would love to ask my TA about this, but every time I as him something he answers a completely different question...
Any thoughts on what's going on here? Perhaps a point in the right direction at least?

The problem is that your makefile includes -ansi -pedantic-errors flags for the compiler. This forces it to use a very old version of C. Perhaps this Makefile was provided by your instructor and he wants like that? It is not uncommon.
To use these new features (// comments, automatic variables anywhere in a block) just drop these two flags. If you have the freedom, I recommend also using -std=c99 -Wall.

To get GCC to accept C99 conventions, tell it to do so:
gcc -std=c99 ...
gcc -std=gnu99 ...
So, add -std=gnu99 to your CFLAGS value, and remove -ansi which is equivalent to -std=c89. If you must code to C89 standards, do not use // comments.
We can't tell what causes the core dump - but it could be that you're trying to modify a string literal somewhere, or any of a large number of other problems.

The -ansi -pedantic-errors prevents the impurities like // and variable definitions in the middle of the function. Remove that and you should be able to sin away.
As for the segmentation fault, your best bet is to run your program through gdb to see where it crashes.

Why are you compiling by calling gcc directly instead of using the makefile? The makefile adds a number of additional command-line gcc options which are most likely important. Do you see the same behavior if you compile using make all?
Since you are new to C, I would recommend adding -Wall to the CFLAGS line. This will enable all compiler warnings, which may alert you to a subtle error that you might have otherwise missed.

Related

Any possibilities that makefile can use different compilers by flag and find variable gcc paths?

Are there any possibilities that makefile can use different compilers by flag and find variable gcc paths? System is Linux.
So the goal should be anything like to say in command line "make CC=..." and it should use one of two possible compilers and should find the path to the second one (first compiler is standard gcc) in a way kind of "automatically". Is this possible?
For example:
First compiler:
CC := gcc
Second compiler first path:
CC := /path-to-compiler-1/gcc
Second compiler second path:
CC := /path-to-compiler-2/gcc
Unfortunately I have no clue how to realize that in an elegant way.
Edit:
The background about the two different compilers is, that the first is the standard linux gcc and the second for mips optimized gcc. So I just want to compile in both ways, compiling for mips on embedded site and standard compilation on normal linux site if necessary. Or another possiblity would be to compile both executables at the same time. The mips compiler is listed under a path that begins in all cases with /home/user. Thereby the folder user is variable and maybe there is another superordinate folder. Concerning this the makefile should find the right path for to the mips gcc.
Do you mean this?
CC = $(if $(COMPILER),$(COMPILER),gcc)
CFLAGS = -std=c11 -pedantic -Wall
all:
$(CC) $(CFLAGS) -o demo demo.c
clean:
rm -f demo
You can launch your Makefile with:
make COMPILER=gcc
or with
make COMPILER=clang
and if you don't provide any argument
make
the default is gcc

C compiler confusion

okay so I'm on OS and I use terminal to compile my c code. Whenever I make a file using nano or vim called "tst.c" (or whatever the name might be ) then I compile using (my teacher told me to use this everytime so I don't think this is the problem:
gcc -Wall -std=c99 -o tst.c ./tst.c
then it turns into binary I'm guessing. But when I try to edit it again, it has all these weird encryptions I'm guessing like:
��������H���__PAGEZERO��������������������������������������������������������ÿ��__TEXT����������������������������������������������������__text����������__TEXT����������`�����*�������`���������������Ä������������__stubs���������__TEXT����������ä������������ä��������������Ä�����������__stub_helper���__TEXT����������ê������������ê���������������Ä������������__cstring�������
So, question is, how do I revert so I can edit and not make a new file every time???????
You're overwriting your original source file with the compiled executable because of the -o option:
gcc -Wall -std=c99 -o tst.c ./tst.c
^^^^^^^^
You'll need to specify a different output file name in the -o option:
gcc -Wall -std=c99 -o tst tst.c
Otherwise, you can leave the -o option off entirely, and the compiled executable will be written to a file named a.out.
Eventually, you'll want to automate all of this with the make utility, but for now just be aware of how the -o option works.
the -o (name) flag means you are storing the output into whatever you used for name.. so if you add .c to the end of the name you'll see lots of interesting stuff. Man pages are pretty awesome when learning about what each flags do.

how to write a makefile in linux for a c program

i have written a c program for doubly-linked-list in linux. the program is named as program2.c.
i have compiled it using "cc program2.c -o out2".
it compiled and also executed fine.
even also tried writing a makefile.my makefiel includes
all:doublelinkedlist
doublelinkedlist:program2.c
gcc -Wall -Werror -O2 -o $# $<
clean :
\rm -fr doublelinkedlist
when i did make it gives me the errors.
can any one please help me writing a makefile.
When using a makefile, you also started using the -Wall -Werror flags. This is a very good thing.
Now the compiler looks for more suspicious things in your program, and refuses to compile if it finds anything. This can be a great help in catching bugs.
However, these warnings mean your program doesn't compile, and you'll need to fix them, by changing the code so that the compiler will be sure all is OK (as far as the compiler can check - of course the code can still contain bugs).
Common issues are mixing different types and not paying attention to the const keyword. But for help with specific warnings, you'll need to show the warnings and the code. Or better - search for each of them in StackOverflow, and I'm sure you'll find good answers.

C program links to wrong version of function

I'm trying to debug an issue where the wrong version of a function gets called causing a segfault. The code that I'm compiling is machine generated and includes a function called 'times' that does a complex multiply of it's two arguments. This code is compiled to a .o before being linked into a higher level object file.
When run this code segfaults and gdb indicates that it's in glibc's version of 'times' which doesn't even take the same number of arguments. The are no instances of '#include anywhere in this code.
Changing the name of times to times1 resolves the problem. This isn't a long term solution though due to the machine generated nature of the code and manually editing the name of this function all the time is unappealing.
The whole mess compiles cleaning with -Wall so I'm not sure where to look. Any ideas on how to resolve this?
Compile chain:
gcc -Wall -I. -g --shared -o dpd.o -fPIC *.c (mahine generated code here)
gcc -g --std=c99 -c -fpic getData.c -I/usr/local/include -L/usr/local/lib -lmatio -I/usr/local/include/iverilog -I$(MATLAB)
gcc -g -shared -o getData.vpi getData.o $(MATLAB)/dpd.o -lvpi -lmatio -L/usr/local/lib
C only uses the name of a function as an identifier, so any two (exported) functions with the same name will conflict. The normal approch is to prefix all exported names in a library with a unique prefix. The other alternative is to use C++ as "a better C" and simply build your C code using a C++ compiler, making use of C++ name mangling.
So the real answer to this one is to throw -fno-builtin-times to gcc. That avoids the problem neatly with no fuss.
This of course assumes that you can't changes the name of times to something that doesn't conflict with a glibc provided function.

Alias CC to Refer to Clang in a Shell?

Any caveats or gotchas to aliasing cc to refer to Clang within my default shell - zsh (presumably by editing my .zshrc file) while leaving cc aliased to gcc in another shell (bash)?
I find Clang much easier to use mainly because it's warnings and error messages are much more readable and understandable than those of gcc. I will be enrolled in a Unix programming course next semester (purely in C) and am expected to have cleared any gcc -Wall warnings before submission of an assignment.
What I am trying to do is do most of my developing using Clang within my default shell (zsh) using a makefile that refers to the compiler as just cc. Once satisfied I would run it once, as a test, via bash (invoking gcc as the compiler) before submitting. The submitted makefile with cc as the compiler would then invoke gcc for the instructor, making it transparent to them. I am supposed to submit makefiles with each assignment.
I know this just seems like lazyness since I can re-edit the makefile each time, but I am trying to leave less room for error.
Just run
make CC=clang
or
make CC=gcc
or perhaps
make CC='gcc -flto -Wall'
(reminder: -flto should be passed at compile and at link time).
I won't comment on whether this is fine or not, but there is an easier way. Just use a variable in your Makefile to whatever you want the default to be:
CC=gcc
Then you can override this when you invoke make:
make CC=clang

Resources