Ubuntu Message Queue Makefile Error - c

I have a problem with message queues in C in Ubuntu. I use VirtualBox to run the Ubuntu.
I took error which is "undefined reference to mq_open. ld returned 1 exit status".
I know there is a same question as this but I tried that solution but it did not worked, so I want to ask again. Please help!
Here is my code, it is really simple but I can not even compile it.
this is my deneme.c
#include <stdlib.h>
#include <mqueue.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include "sharedMsg.h"
int main()
{
mqd_t mq;
mq = mq_open(MQNAME, O_RDWR | O_CREAT, 0666, NULL);
}
this is my sharedMsg.h
struct item{
char *word;
int lineNum;
};
#define MQNAME "/sentmsg"
and finally this is my MakeFile
all: deneme
deneme: deneme.c
gcc -g -Wall -o deneme deneme.c -lrt
clean:
rm -fr *~ *.o

The problem with your Makefile is that your all target depends on demene but the target that specifies -lrt is called demene1. Thus, the default inference rules kick in and demene is attempted to be linked without -lrt. The rule for deneme1 is also wrong in that it attempts to create a binary named deneme, even though the rule should create deneme1. To resolve this, change the first to third lines to
all: deneme1
deneme1: deneme.c
gcc -g -Wall -o deneme1 deneme.c -lrt
or the second line to
deneme: deneme.c

(Note: The OP has edited the question and fixed the Makefile after this answer)
You have a broken Makefile.
The reason why you've even seen the linker error is that you have probably executed make deneme. In that case make will try to compile dename.c with default compiler options (because it did not find a target called deneme) and the default options do not include -lrt.
You have to fix your Makefile (replace deneme1: with deneme:)
all: deneme
deneme: deneme.c
gcc -g -Wall -o deneme deneme.c -lrt
clean:
rm -f deneme *~ *.o

Related

Issue compiling with a new module on Linux

I'm trying to compile a project that contains different modules (.h files) so I'm using a makefile. I added a new module called semaphore_v2.h which I included in another module called connection.h. connection.h is included into jack.c where the main process is. When compiling using make command, I get the following error:
Seems like despite I included the module, it doesn't keep track of the references of the semaphore_v2.h module and I can't find the issue here. What's wrong?
makefile:
all: compilation
jack.o: jack.c
gcc -c jack.c -Wall -Wextra
semaphore_v2.o: semaphore_v2.c semaphore_v2.h
gcc -c semaphore_v2.c -Wall -Wextra
files.o: files.c files.h
gcc -c files.c -Wall -Wextra
connection.o: connection.c connection.h
gcc -c connection.c -Wall -Wextra
compilation: jack.o files.o connection.o
gcc jack.o connection.o files.o -o jack -Wall -Wextra -lpthread
connection.h
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <time.h>
#include "files.h"
#include <ctype.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "semaphore_v2.h"
typedef struct {
int socketfd;
int memid;
semaphore *sinc;
}thread_input;
...
jack.c
#include <signal.h>
#include "connection.h"
...
You should change your makefile compilation target to include also semaphore_v2.o
so you should have such a line at your makefile:
compilation: jack.o files.o connection.o semaphore_v2.o
gcc jack.o connection.o files.o semaphore_v2.o -o jack -Wall -Wextra -lpthread
Note semaphore_v2.o appears twice, one time as a dependency to this target and one time as input to the gcc command.

Header file is included, but still undefined reference

I have simplified the code to the minimum
#include "frozen.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
int main()
{
char *json = "{ \"a\": 123, \"b\": \"hi\", c: true }";
int value = 0;
json_scanf(json, strlen(json), "{c: %B}", &value);
printf("Hello World\n");
// assert( json != NULL );
printf( "json: %s\n", json );
printf( "json.c: %s\n", value );
// free( json );
return 0;
}
directory structure:
/home/projects/json-test/main.c
/home/projects/json-test/frozen/{contents of https://github.com/cesanta/frozen repo}
What I do:
gcc main.c -Ifrozen -o main
What is being displayed in output:
main /tmp/ccsYWNAP.o: In function `main': main.c:(.text+0x43):
undefined reference to `json_scanf' collect2: error: ld returned 1
exit status
I have very limited knowledge in C, thus I may be missing some steps, so take into account that I literally did not do anything else than written above, maybe I should have. I am used to loosely typed php/js/python kind of languages, but I was reading that just including file does not tell gcc that "you should search for json_scanf inside frozen.h". Should there be some sort of a "glue", or "linking" step I am missing?
UPDATE: Based on responses, I have created this Makefile:
CC = gcc
FLAGS = -std=c99
DEST_DIR = ./bin
DEST_PATH = "$(DEST_DIR)/main"
BUILD_DIR = ./build
all: clean directories json main.o
$(CC) $(BUILD_DIR)/*.o -o $(DEST_PATH) $(FLAGS)
main.o: src/main.c $(BUILD_DIR)/frozen.o
$(CC) src/main.c -c -o $(BUILD_DIR)/main.o $(FLAGS)
json: json.o
json.o: src/frozen/frozen.c src/frozen/frozen.h
$(CC) src/frozen/frozen.c -c -o $(BUILD_DIR)/frozen.o $(FLAGS)
clean:
rm -rf $(BUILD_DIR)
directories:
mkdir -p $(DEST_DIR)/
mkdir -p $(BUILD_DIR)/
And changing #include "frozen.h" to #include "frozen/frozen.h", and running make, creates build/main file that can be successfully ran with ./bin/main command. Thank you!
Ugh. You don't have a mistake. The library developer has some really bad coding practices. Basically, for whatever reason, his header is not sufficient for compilation. If you look at the unit_test.c in the repository of frozen, you will see he's actually including frozen.c instead of frozen.h. If you change your #include "frozen.h" to #include "frozen.c" it will work fine. The other option is to provide the .c file explicitly:
gcc frozen/frozen.c main.c -Ifrozen
Normally, you'd put everything in the header, or require the library to be compiled, as a .a file and then linked when you use it, but he hasn't provided a makefile that does that.
EDIT: You can also compile frozen.o beforehand, but the library's author should've really provided a makefile to do that...
gcc -c frozen.c -o ../frozen.o
cd ..
gcc main.c frozen.o -Ifrozen

gcc compile multiple files

I have these five source
main.c src_print1.c src_print2.c header_print1.h header_print2.h
the contents are simple and are as following for respective files:
main.c
#include "header_print1.h"
#include "header_print2.h"
int main(int argc, char** argv) {
print1();
print2();
return 0;
}
header_print1.h
#ifndef PRINT_1
#define PRINT_1
#include <stdio.h>
#include <stdlib.h>
void print1();
#endif
header_print2.h
#ifndef PRINT_2
#define PRINT_2
#include <stdio.h>
#include <stdlib.h>
void print2();
#endif
src_print1.c
#include "header_print1.h"
void print1() {
printf("Hello 1\n");
}
src_print2.c
#include "header_print2.h"
void print2() {
printf("Hello 2\n");
}
Using gcc I have tried to compile using the following command line:
gcc -I ./ -o test -c main.c src_print1.c src_print2.c
Everything is in the same folder.
The error I get is:
gcc: cannot specify -o with -c or -S with multiple files
I looked up at gcc manual, but actually I don't understand what to do in this case, since usually I use IDE and not the command line.
IMHO, if you rewrite your compilation statement like
gcc -I./ -o test main.c src_print1.c src_print2.c
You'll be good to go. There is no need for -c flag [NOTE] when you're specifying the output binary using -o.
Also, as mentioned here, all the files are in same directory, you can even shorten the statement as
gcc -o test main.c src_print1.c src_print2.c
Suggestion: While the above change(s) will do the job, this is not considered an elegant way of doing so. Please consider creating a makefile which will make your life easier.
[Note]:
Regarding the -c option, as per the online gcc manual, (emphasis mine)
-c
Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
So, it should be clear by now, why you got the error.

Compiling using multiple headerfiles in GCC -- undefined reference to .. math

I've been working on this for a while now. I have these files:
main.c
zSim.h
zSim.c
zDynamicArray.h
zDynamicArray.c
zOptions.h
zOptions.c
zMain.h
zMain.c
All of the files and headers are located within the same folder.
My main has the following includes:
#include "zDynamicArray.h"
#include "zOptions.h"
#include "zMain.h"
#include "zSim.h"
#include <stdio.h>
#include <math.h>
I am using header guards. Just for example, this is from my zSim.h file:
#ifndef SIM_H
#define SIM_H
#include "zDynamicArray.h"
#include "zOptions.h"
//This Header is accountable
//for all Simulation Related things.
int Simulate(SIMOPT so,PRINTOPT po);
#endif
and this is a snippet from my zSim.c code (maybe I am doing something wrong here?):
#define M_PI 3.14159265358979323846
#include "zSim.h"
#include "zDynamicArray.h"
#include "zOptions.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
I am compiling using this gcc command:
gcc main.c zSim.c zOptions.c zDynamicArray.c zMain.c -o TEST
and I also used:
cc -c main.c
cc -c zSim.c
cc -c ... etc
cc *.o -o TEST
They all result in an undefined reference for anything in the math.h library. Also when I use the gcc -I command, math is still undefined.
If i compile using gcc main.c, I get unresolved references for anything in my header files.
What should I do?
try ading -lm at the end : gcc -c main.c cc -c zSim.c cc -c ... etc cc *.o -o TEST -lm
You have to link the math library with the -lm option. The reason why is explained here : Why do you have to link the math library in C?
they all result in an undefined reference for anything in the math.h library
math.h is only the header file which contains prototypes and type declarations. You also need to link against the math library when creating your executable. Add -lm to your gcc call:
gcc main.c zSim.c zOptions.c zDynamicArray.c zMain.c -o TEST -lm
See also Undefined reference to `sin`.

Include a source file in a C program

How can I include foo() function of foo.c in this small program (sorry for my noob question):
In my foo.h file:
/* foo.h */
#include <stdio.h>
#include <stdlib.h>
int foo(double largeur);
In foo.c:
/* foo.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int foo(double largeur)
{
printf("foo");
return 0;
}
And in main.c:
/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
printf("Avant...");
foo(2);
printf("Apres...");
return 0;
}
After compiling:
$ gcc -Wall -o main main.c
I get this error:
Undefined symbols: "_foo",
referenced from:
_main in ccerSyBF.o ld: symbol(s) not found collect2: ld
returned 1 exit status
Thanks for any help.
$ gcc -Wall -o main main.c foo.c
GCC doesn't know to look for foo.c if you don't tell it to :)
Creating a program in C requires two steps, compiling and linking. To just run the compiling part, use the -c option to gcc:
gcc -c main.c
This creates an object file, main.o (or main.obj on Windows). Similarly for gcc -c foo.c. You won't get the error message above at this stage. Then you link these two object files together. At this stage, the symbol foo is resolved. The reason you got the error message was because the linker couldn't find the symbol, because it was only looking at main.o and not foo.o. The linker is usually run from gcc, so to link your object files and create the final executable file main, use
gcc -o main main.o foo.o
You have to compile foo.c also because it is another module. Let me see how they do it in gcc:
$ gcc -Wall main.c foo.c -o main
You could also do this in your MakeFiles, like this:
APP_NAME = Foo
Foo_HEADERS = foo.h
Foo_FILES = main.c foo.c
If you're not so much familiar with MakeFiles i suggest you to take a look at Make Docs, but this is a simple example, APP_NAME sets the name of the compiled executable(in this case is Foo), Foo_HEADERS will set the headers used by your application, Foo_FILES you will set the source files of your applications, remember to put the APP_NAME(in this case Foo) at the beginning of _HEADERS and _FILES. I suggest you to use MakeFiles because they will organize you application build process and will be better for the end-user.

Resources