gcc g option on compile or build? - c

I know -g option is used for debugging by putting debug symbols on execute file.
I wonder where to put -g option either compile or build may be both.
If I have 2 .c files to build ab.out, where is the correct place to put -g option and why?
gcc (1) -c -o a.o a.c
gcc (2) -c -o b.o b.c
gcc (3) -o ab.out a.o b.o

Related

Cross compile SDL2 in C for Windows on Linux

I have an SDL2 program that I've been developing on Ubuntu that I'd like to compile for windows. Right now I compile and run it with a makefile like this:
OBJECTS = main.o text.o object.o vector.o physics.o shapes.o target.o
run: all
./a.out
all: $(OBJECTS)
gcc $(OBJECTS) `sdl2-config --cflags --libs` -lSDL2_ttf -lSDL2_image -lm -ldl
main.o: main.c defs.h
gcc -c main.c `sdl2-config --cflags --libds` -lSDL2_ttf
text.o: text.c text.h defs.h
gcc -c text.c
object.o: object.c object.h defs.h
gcc -c object.c
vector.o: vector.c vector.h defs.h
gcc -c vector.c
physics.o: physics.c physics.h defs.h
gcc -c physics.c
shapes.o: shapes.c shapes.h defs.h
gcc -c shapes.c
target.o: target.c target.h defs.h
gcc -c target.c
clean:
rm *.o
I'd suggest quasi-msys2 cross-compilation environment (I'm the author).
From the first glance, your makefile should work in it with minimal changes:
sdl2-config doesn't work there (which is a minor defect), but pkg-config does.
Replace sdl2-config with pkg-config sdl2 SDL2_image SDL2_ttf (followed by --libs and/or --cflags).
Then -lSDL2_ttf -lSDL2_image should be removed, since pkg-config is going to output those anyway.
Note that pkg-config ... --libs should be used when linking, and pkg-config --cflags should be used when compiling (same with sdl2-config).
-ldl should be removed. -lm is unnecessary, but should be harmless.
gcc should be replaced with $CC to pick up the compiler from the environment variable.
While this doesn't affect correctness, manually specifying .h dependencies in makefiles is error-prone and tedious. Instead you should be compiling with -MMD -MP flags, to automatically generate the dependencies.
Since removing the dependencies makes all your .o recipes look very similar, you can deduplicate them into a single recipe:
%.o : %.c
$CC -c $< -MMD -MP
-MMD -MP is going to produce .d files (tiny makefile pieces), which need to be included using -include $(OBJECTS:.o=.d).
With those fixes, the makefile should work in quasi-msys2, except that the resulting executable is going to be called a.exe and not a.out...
# We're going to cross-compile with Clang. Install Clang, LLD, Wine. Then...
# Clone the repo
https://github.com/HolyBlackCat/quasi-msys2
cd quasi-msys2
# Install the necessary packages
make install _gcc _SDL2 _SDL2_image _SDL2_ttf
# Open the cross-compilation shell
# Among other things, this sets `CC` to a wrapper for Clang that invokes it
# with the right flags, and sets env variables for `pkg-config` to find the
# newly installed libs.
env/shell.sh
Then just run make as usual.

How to create command in bash to compile multiple C program with multiple flags

So my file structure is basically this -
I have a .zshrc file since I'm on OS X
I have a .my_custom_commands.sh file which contains the shortcuts I want
In my .zshrc I source the commands file
Currently, I'm looking for a solution to compile multiple files with flags using the "gcc" command
For example, if I want to compile a.c and b.c
gcc -Wall -Werror -ansi -pedantic -o output.c a.c b.c
However, I don't want to type this out every time, so I was thinking there would be a way to create a custom command say 'gccf' (gcc flags). The thing is that I don't know zsh programming language so I'm just wondering if there is a way to pass multiple args into the function I created in the commands file.
I have something like this right now
function gccf() {
gcc -Wall -Werror -ansi -pedantic -o output.c $1 $2
}
I understand that the args you pass into the command line are represented by $1, $2..., but is there anyway to check how many args have been passed? Because if $2 isn't passed then this won't work I think.
Set CFLAGS as you want and just use the default rules for make. You don't even need a makefile:
$ rm -f Makefile
$ ls a.c
a.c
$ make a
cc a.c -o a
$ rm -f a.o a
$ export CFLAGS=-pedantic
$ make a
cc -pedantic a.c -o a
If you have multiple source files, you'll need a (trivial) makefile:
$ rm -f a *.o output Makefile
$ unset CFLAGS
$ make a
cc a.c -o a
$ export CFLAGS='-Wall -Werror -ansi -pedantic'
$ rm a; make a
cc -Wall -Werror -ansi -pedantic a.c -o a
$ printf 'output: a.o b.o\n\t$(CC) $(LDFLAGS) $^ -o $# $(LDLIBS)\n' > Makefile
$ make output
cc -Wall -Werror -ansi -pedantic -c -o a.o a.c
cc -Wall -Werror -ansi -pedantic -c -o b.o b.c
cc a.o b.o -o output
$ rm -rf *.o output
$ export CC=gcc LDLIBS=-lm
$ make output
gcc -Wall -Werror -ansi -pedantic -c -o a.o a.c
gcc -Wall -Werror -ansi -pedantic -c -o b.o b.c
gcc a.o b.o -o output -lm
In other words, don't try to reinvent the wheel. Your use case has been encountered by many people, and there are long standing conventions and tools in place to enable the work flow.
Note that you may want to include LOADLIBES along with LDLIBS, but the former name should (probably?) no longer be used.
In Bourne-heritage shells (e.g. sh, zsh, bash, ksh), to specify all arguments passed to a program or function, use "$#" (including the double quotes!), which expands to any number of args passed, including none.
But if you follow the Unix philosophy of using the one tool that does just one thing, you want to look at make as suggested in comments and other answers.
PS: you also want -o output, not -o output.c, since your program is not a C source file, but an executable.

Linking static library with -l flag

How can I have my makefile compile with the -l flag?
I have a makefile that looks like
myLibrary:
gcc -c myLibrary.c -o myLibrary.o
ar cr libmyLibrary.a myLibrary.o
and then I compile my main program with
main:
gcc -g -c -o main.o main.c
gcc main.o -o main libmyLibrary.a
The above makefile works, but if I want to replace
libmyLibrary.a
with -lmyLibrary I get an error. Shouldn't both be working the same?
Here is a rudimentary, unrealistic makefile that will make the static library libmyLibary
before it makes the program main, which it will link with the static library
using the -L (library search-path) and -l (library) options.
Makefile
.PHONY: all clean
all: libmyLibrary.a main
main: main.o | libmyLibrary.a
$(CC) -o main main.o -L. -lmyLibrary
libmyLibrary.a: myLibrary.o
$(AR) rcs libmyLibrary.a myLibrary.o
clean:
rm -f *.o libmyLibrary.a main
which runs like:
$ make
cc -c -o myLibrary.o myLibrary.c
ar rcs libmyLibrary.a myLibrary.o
cc -c -o main.o main.c
cc -o main main.o -L. -lmyLibrary
As I think you know, it's unrealistic to make both a library and a program
that links with it in the same makefile, since the point of a library is
that you don't need to keep remaking it to link it with many programs. You'd really have
a makefile for libmyLibrary.a and other makefiles for programs that
use it.
This is how the gcc linkage options -L and -l work:
-L/path/to/search
tells the linker to look for any libraries that you specify with the -l option in /path/to/search,
before it looks for them in its default search directories. The current directory, .,
isn't one of the linker's default search directories. So if you want it to
find a library specified with the -l option in the current directory, then you need to
specify -L.
-lfoo
tells the linker to search for either a dynamic library, libfoo.so, or a static
library, libfoo.a, first in your -L directories, if any, in the order you've
specified them, and then in its default search directories. It stops searching
as soon as if finds either libfoo.so or libfoo.a in one of the search directories.
If it finds both of them in the same directory, then by default it will link libfoo.so with
your program and not link libfoo.a.
To link purely statically library, use -static, Like
gcc -static main.c libmyLibrary.a
And run executable file ./a.out GCC Linux.

How to compile with a .o file that was compiled with other .o files (C99)

consider c.c a code that includes a.h and b.h, and main.c a code that includes c.h
i tried to compile it like so
gcc --std=c99 -o a.o -c a.c
gcc --std=c99 -o b.o -c b.c
gcc --std=c99 -o c.o -c c.c a.o b.o
but when I run the last one, gcc yells at me
gcc --std=c99 -o c.o -c c.c a.o b.o
gcc: warning: a.o: linker input file unused because linking not done
gcc: warning: b.o: linker input file unused because linking not done
and then when I try to compile the main.c file using gcc -o main main.c c.o it says that there are a lot of undefined references, which is predictable once the c file was not correctly compiled.
I've seen some similar questions here at stackoverflow, but I couldn't get it to work neither way.
I'm on Arch Linux running gcc v4.9.2-3
First, it is -std=c99 with a single dash.
I guess you are on Linux.
Then, you always should pass -Wall -Wextra -g (especially since you are a newbie) to gcc : -Wall ask for nearly all warnings, -Wextra for even more warnings, -g ask for debug information.
At last, you want to produce an executable myprog (don't name executables as c.o, this is supposed to be an object file) with
gcc -std=c99 -Wall -Wextra -g -o myprog c.c a.o b.o
You need to remove any -c since you want the linking to happen.
If you really mean -but that is very unusual today, better make shared libraries!- to agglomerate several object files into one all.o (to be linked later with other objects) you might try the -r linker option
gcc -std=c99 -Wall -Wextra -g -r c.c a.o b.o -o all.o
But last time I tried it was in the previous century, so details could be wrong.
There are very few reasons to agglomerate objects using the -r linker option. Unless you really know what you are doing, you are very probably wrong (in trying -r).
Perhaps you want to make a software library. These days it is much better to make a shared library. A shared library (technically an ELF shared object) should contain position independent code. So, assuming you have three translation units t1.c, t2.c, t3.c you first compile them as PIC :
gcc -std=c99 -Wall -Wextra -g -fPIC t1.c -c -o t1.pic.o
gcc -std=c99 -Wall -Wextra -g -fPIC t2.c -c -o t2.pic.o
gcc -std=c99 -Wall -Wextra -g -fPIC t3.c -c -o t3.pic.o
then you link all these PIC object files into a shared library libmyt.so
gcc -std=c99 -Wall -Wextra -g -shared \
t1.pic.o t2.pic.o t3.pic.o \
-o libmyt.so
Later you'll use this shared library e.g. as
gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . libmyt.so
or as
gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . -L. -lmyt
You might consider static linking with ar to make a static library libmyt.a but I don't recommend that.
Of course, you'll debug your program using gdb ./myprog and you could try running it with ./myprog. To use valgrind, try valgrind ./myprog
If you have several translation units, better learn how to use GNU make. Read the Program Library HowTo and this and these hints.

How can I compile with shared library if I use Autotools

I have two C programs named drive.c and mylib.c.
drive.c is main module mylib.c is sub modulle that I want work as shared library .
I can compile them with following step and run.
gcc –fPIC –g –c –Wall mylib.c
gcc -shared -Wl,-soname,libmylib.so.1 -o /c/opt/lib/libmylib.so.1.0.1 mylib.o -lc
gcc -g -Wall -Wextra -pedantic -I./ -L/c/opt/lib -o drive.exe drive.c –l:libmylib.so.1
Now I want know is How can I compile them by autotools as same effect of above way ?
What and how do I have to edit configure.ac and Makefile.am for compile them?

Resources