Im working with C on MacOS, when i compile the program by myself with
gcc main.c -o prog $(sdl2-config --cflags --libs)
It works fine, but when i try to make it work with a makefile i keep facing this error
gcc -o main.o -c main.c prog
clang: warning: prog: 'linker' input unused [-Wunused-command-line-argument]
main.c:1:10: fatal error: 'SDL.h' file not found
#include <SDL.h>
There is my code
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
int main (int argc, char **argv)
{
SDL_Window *window = NULL;
if ( SDL_Init(SDL_INIT_VIDEO) != 0)
{
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
exit(EXIT_FAILURE);
}
window = SDL_CreateWindow("Bomberman", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_MINIMIZED);
if (window == NULL)
{
SDL_Log("Unable to create window: %s", SDL_GetError());
exit(EXIT_FAILURE);
}
bool window_open = true;
while (window_open)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
window_open = false;
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
And here is my makefile
main.o: main.c
gcc -o main.o -c main.c prog $(sdl2-config --cflags --libs)
Well, look at the command you ran from the compile line:
gcc main.c -o prog $(sdl2-config --cflags --libs)
This builds an output prog from the source file. And compare it to your recipe:
gcc -o main.o -c main.c prog $(sdl2-config --cflags --libs)
^^^^^^^^^^^^
They aren't the same, so clearly you won't get the same result. Plus you've told make you're trying to build the output file main.o, not prog as your command line version does.
First, remove the extra stuff and fix the target.
Second, $ is special to make (it introduces a make variable). So in your makefile recipe $(sdl2-config --cflags --libs) is actually expanding a very oddly-named make variable.
You want this:
prog: main.c
gcc main.c -o prog $$(sdl2-config --cflags --libs)
Make already defines a builtin rule for building .o files from .c files with the same base name. You should use that and the standard FLAGS variables. So you end up wanting something like:
CFLAGS = $$(sdl2-flags --cflags)
LDLIBS = $$(sdl2-flags --libs)
With just that, you can type make main.o to compile main.o and make main to build an executable main from main.o (if it exists) or main.c (if there's no main.o already)
If you want to build prog, you can add a rule
prog: main.o
$(CC) $(LDFLAGS) -o $# $^ $(LDLIBS)
Related
I wrote a makefile which builds a C program attaching the x.264 header. After trying to execute the makefile in terminal I receive the fatal error:
"example.c line [line of #include ] x264.h no such file or directory". Below you can find the C code and makefile (located in the same folder, the library - containing the x264.pc file- is in the folder libx264 of the parent folder). I would be very grateful if you could help with the linkage.
Makefile:
CC = gcc
CFLAGS = -c -Wall `export PKG_CONFIG_PATH=../libx264 && pkg-config --cflags x264`
LDFLAGS = -static `export PKG_CONFIG_PATH=../libx264 && pkg-config --libs --static libx264`
all: Release
Debug: CFLAGS += -g
Debug: example
Release: example
test: example.o
$(CC) -o example example.o $(LDFLAGS)
test.o: example.c
$(CC) $(CFLAGS) example.c -o example.o
clean:
rm -f example.o example
example.c code
#include <stdio.h>
#include <x264.h>
int main( int argc, char **argv )
{
int width, height;
return 0;
}
You'd need to tell the compiler (to be more precise: the preprocessor) where the header file is using the -I option:
CFLAGS = -c -Wall -I../libx264
If I'm right, you need to unpack that .pc file, so that x264.h is indeed in ../libx264.
Similar thing for the linker flags (assuming there's a libx264.a file in ../libx264), where you have to specify where the library is using the -L option:
LDFLAGS = -static -L../libx264 -lx264
Alternatively you could of course also write:
LDFLAGS = -static ../libx264/libx264.a
I would apreciate any insights to a couple of linker and compiler issues I have
I have main.c file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "assemble.h"
char *fileName;
FILE *file;
int main(int argc, char *argv[]){
char inputFile[MAX_INPUT];
int i, flag = TRUE;
for(i=1; i<argc; i++){
fileName = argv[i];
strcpy(inputFile,argv[i]);
file = fopen(inputFile,"r");
}
flag = assemble(file, fileName); //****this is the problam line****
if(!flag)
printf("Errors found, compilation aborted\n");
else
printf("File %s compiled\n", fileName);
fclose(file);
return 0;
}
In the header assemble.h I have the decleration:
int assemble(FILE *file, char *fileName);
The first issue is in main.c I get undefined referance to 'assemble', id returned 1 exit status
The second issue is in assemble.h I get FILE was not declared in this scope.
Does anyone know what causes these errors and what is the fix?
Thanks in advance
[EDIT]: the makefile.
assembler: main.o assemble.o functions.o
gcc -Wall -ansi -pedantic main.o assemble.o functions.o -o assembler -lm
main.o: main.c assemble.c
gcc -Wall -ansi -pedantic -c main.c assemble.c -lm
assemble.o: assemble.c
gcc -Wall -ansi -pedantic -c assemble.c -lm
functions.o: functions.c
gcc -Wall -ansi -pedantic -c functions.c -lm
clean:
rm -f assembler
rm -f *.o
You need to compile both files and link them together.
gcc main.c assemble.c
Or compile them separately to object files and link them.
gcc -c main.c
gcc -c assemble.c
gcc main.o assemble.o
There are 4 files:
helper.h //contains the signatures of functions in helper.c
helper.c //implements the signatures in helper.h
file.h //has all the includes needed to run file.h
file.c //this file includes file.h and helper.h
In file.c, I need to use the function that is defined in helper.c in my main function. However, file.c is saying that there is an undefined reference to 'func_found_in_helper.c'
Is this structure correct?
Yes, provided file.c contains
#include "helper.h"
and when building your program you link together helper.o and file.o.
You also need to ensure you compile each of the files with -c so that the compiler only compiles (and not links); do the link later with all the object files.
Here's a working example (I don't actually need a main.h but if you have one of those, #include it from main.c):
main.c
#include <stdio.h>
#include <stdlib.h>
#include "helper.h"
int
main (int argc, char **argv)
{
test ();
exit (0);
}
helper.c
#include <stdio.h>
void
test ()
{
printf ("Hello world\n");
}
helper.h
void test ();
To compile
gcc -Wall -Werror -c -o main.o main.c
gcc -Wall -Werror -c -o helper.o helper.c
To link
gcc -Wall -Werror -o test main.o helper.o
In a Makefile
test: main.o helper.o
gcc -Wall -Werror -o test main.o helper.o
%.o: %.c
gcc -c -Wall -Werror -o $# $<
clean:
rm -f *.o test
To run
$ ./test
Hello world
It's a bit difficult to tell what else might be wrong without the program; my guess is you simply forgot the -c flag to gcc, or forgot to link in helper.o.
undefined reference to 'func_found_in_helper.c'
That's a little odd, as it suggests you have tried to call the function using the '.c' extension, rather than just the function name. Maybe the '.' is just a typo in the question ?
Also a linker will flag an undefined symbol, so it may also be that you have not told the linker where to find helper.o ( the helper.c file compiled to the an object file ). The compiler will start the linker automatically. Did you compile helper.c first ?
According to this question, gcc's -l command requires your library to be named libXXX.a.
Is there a way to link a static library using a different command with gcc? The goal is to avoid this lib- prefix.
Just pass the library as in input file like so:
gcc main.c yourlibrary.a -o prog
Like nunzio said. Just pass it in directly as an input file. He beat me to it, but here's a full example anyway.
mylib.c:
#include <stdio.h>
void say_hi(void)
{
printf("hi\n");
}
main.c:
extern void say_hi(void);
int main(int argc, char**argv)
{
say_hi();
return 0;
}
Makefile:
main: main.c mylib.a
gcc -o main main.c mylib.a
mylib.a: mylib.o
ar rcs mylib.a mylib.o
mylib.o: mylib.c
gcc -c -o $# $^
I realize this assumes some background knowledge in Make. To do the same thing w/o make, run these commands in order:
gcc -c -o mylib.o mylib.c
ar rcs mylib.a mylib.o
gcc -o main main.c mylib.a
I've been confused as to why this specific error is coming up.
The function being called looks the same so I don't think it is a type/case-sensitive error. I've included my makefile, the header in question, and the code snippet of the C file using the header + calling the function.
If anything else would be relevant I could supply it.
Thanks to anyone that helps!
game_state.h
#ifndef GAME_STATE_H
#define GAME_STATE_H
typedef struct Game_Condition_struct {
bool vertical_win;
bool down_diag_win;
bool up_diag_win;
char* player_char;
} GAME;
void Game_Over(BOARD* board);
void Win_Check(BOARD* board, GAME* game_condition);
#endif
moves.c snippet
#include "game_state.h"
... // other code above
else {
Make_Move(board, user_move, player_char);
Print_Board(board);
// IF-ELSE to change the player turn
if (*player_char == 'X') {
*player_char = 'O';
}
else {
*player_char = 'X';
}
Game_Over(board);
}
game_state.c
void Game_Over(BOARD* board) {
GAME game_condition;
Win_Check(board, &game_condition);
}
makefile
connectn.out: board.o main.o read_args.o moves.o game_state.o
gcc -g -Wall -o connectn.out board.o main.o read_args.o moves.o
main.o: board.h read_args.h moves.h game_state.h main.c
gcc -g -Wall -c -o main.o main.c
board.o: board.h board.c
gcc -g -Wall -c -o board.o board.c
read_args.o: read_args.h read_args.c
gcc -g -Wall -c -o read_args.o read_args.c
moves.o: moves.h board.h game_state.h moves.c
gcc -g -Wall -c -o moves.o moves.c
game_state.o: game_state.h board.h game_state.c
gcc -g -Wall -c -o game_state.o game_state.c
clean:
rm *.o *.out
The code works as I expect if I don't include the Game_Over(board) call, so I'm confused as to why it's not defined.
BOARD is a struct I made, similar to GAME.
You didn't link game_state.o into connectn.out. Add game_state.o to the end of the 2nd line of Makefile.