Guillaume Magniadas
Guillaume Magniadas

Reputation: 176

Need help understanding how GCC compilation work on linux and macOS

I recently obtained a macbook so I started learning how to develop project on macOS, to do so, I tried to compile a finished project I made on linux, the .o file got created easily but I had trouble with the executable.

Here is the line :

gcc -Wall -g -O2 `sdl2-config --cflags` head.h -o game.out mainSDL.o container.o update.o user.o -O2 `sdl2-config --libs` -lSDL2_image 

clang: error: cannot specify -o when generating multiple output files
make: *** [game.out] Error 1

(I have sdl2 installed on this pc)

This line was working perfectly under archlinux.

This project compile easily with some basic command like :

gcc container.c mainSDL.c user.c update.c -lSDL2

But I would like to understand what's going on,

Why this error with this line ?

Thanks for your help

Edit : Finally the problem came from this bad makefile which had some useless line and a header in it.

Upvotes: 0

Views: 141

Answers (2)

Luis Colorado
Luis Colorado

Reputation: 12668

You posted

gcc -Wall -g -O2 `sdl2-config --cflags` head.h -o game.out mainSDL.o container.o update.o user.o -O2 `sdl2-config --libs` -lSDL2_image

I'll try to explain the command line, parameter by parameter:

  • -Wall means to the compiler to activate all kinds of warnings. Warnings normally don't mean to stop the compilation, errors do, so activating them all will give a finer approach of the code errors you can be making in the code.
  • -g means to include debug info (source line references) in the executable, to be able to do source debugging.
  • -O2 means to do second level optimisations. This normally makes your code more difficult to debug, as the source line references don't match well with the binary code. It is normal to do -O0 (meaning no optimisation at all) when debugging.
  • sdl2-config --cflags is a command execute by the shell that output the compiling options of the sdl2 library. It normally emits the -I options necessary to find the #include files. It is enclosed in backticks (sorry, but don't know how to show them escaped in code mode) to make the shell to replace the parameter with the output of the sdl2-config command.
  • head.h is an include file.... normally you get that file #included from other files, so it is a mistake to compile it directly. You have to take it away, as it is not intended to be compiled separately.
  • -o game.out means to call the output executable game.out. This names the output file. When you are compiling-only (not linking) separate sources (by use of -c option) and you specify multiple files to compile, it is an error (the one you mention) to specify a single output filename, as each output binary is called after its source, by changing the .c suffix by a .o one.
  • mainSDL.o, container.o, update.o, user.o are object modules, already compiled (these are used only when you are linking a final executable)
  • -O2 is repeated.
  • sdl2-config --libs this is executed by the shell and its output is substituted as the link parameters necessary to be able to link with the sdl2 library. It generates the -L paths necessary to find the library location.
  • -lSDL2_image this means to use the SDL2_image library at link time.

Well, it is fairly bad. The sdl2-donfig --cflags is used to compile only and probably generates (you can try by executing the following command:

sdl2-config --cflags

in the command line by itself), you'll see what options it is giving to the compiler. Most probably, it generates a -c option to compile-only, so this makes all the .o and the -o options unnecessary, and compilation has to be made in two steps (one to compile, one to link)

sdl2-config --libs will append all the -l libraries to the link phase, so it is not necessary to add a -lSDL2_image option.

I suggest to compile your program to use (after trying to guess what you have posted only) the following commands:

gcc -Wall -g -O0 `sdl2-config --cflags` mainSDL.c container.c update.c user.c

(or individually for each source file) to compile-only all source files, and then

gcc -g -O0 -o game.out mainSDL.o container.o update.o user.o `sdl2-config --libs`

to link the result in a final executable.

But I know nothing about your source files, so I don't know if this will give you the correct results.

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361605

`sdl2-config --cflags` head.h

These bits are suspect. Passing a header file to the compiler is almost certainly wrong.

The rest of the line has linking options, but --cflags spits out compile options. From the looks of it, compiling's already complete.

Upvotes: 1

Related Questions