Failing to execute “make” in Ubuntu gcc












-2














I have several files which I'm trying to compile using gcc in Ubuntu. I have vmware machine 16.04 ubuntu, which 64-bit computer. I have added the flags for 32bit compilation in the makefile. (-m32 flag).



This is the makefile:



    all: clean binsem.a ut.a ph
FLAGS = -Wall -L./ -m32


ph: ph.c
gcc ${FLAGS} ph.c -lbinsem -lut -o ph


binsem.a:
gcc $(FLAGS) -c binsem.c
ar rcu libbinsem.a binsem.o
ranlib libbinsem.a


ut.a:
gcc $(FLAGS) -c ut.c
ar rcu libut.a ut.o
ranlib libut.a

clean:
rm -f *.o
rm -f a.out
rm -f *~
rm -f ph
rm -f *a


My attempts to compile the code were not successful, as I received the following error:



ph.c:126:12: warning: ‘main’ defined but not used [-Wunused-function]
/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'ph' failed
make: *** [ph] Error 1


**I tried - **




  1. Adding -c flags to the ph.c file in the make file. However it doesn't make much sense, since it has a main function. No success.


    1. Adding sum -m32 flags in the makefile, in addition to what's already written. No Success.




The file "ph.c", is the following file -



#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <inttypes.h>

#include "binsem.h"
#include "ut.h"



#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int N;

volatile int *phil_state;
sem_t *s;
sem_t mutex;
int *tid;

uint64_t get_wall_time() {
struct timeval time;

gettimeofday(&time, NULL);
uint64_t millis = (time.tv_sec * (uint64_t)1000) + (time.tv_usec / 1000);


return millis;
}

void think(int p) {
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;

for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}

printf("Philosopher (%d) - time %" PRId64 " - is hungryn", p, get_wall_time()); fflush (stdout);
}

void eat(int p){
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is eatingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;
for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}
//printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);
}

void test(int i){
if (phil_state[i] == HUNGRY &&
phil_state[LEFT] != EATING &&
phil_state[RIGHT] != EATING){
phil_state[i] = EATING;

binsem_up(&(s[i]));
}
}

void take_forks(int i){
binsem_down(&mutex);

phil_state[i] = HUNGRY;

test(i);

binsem_up(&mutex);

binsem_down(&(s[i]));
}


void put_forks(int i){
binsem_down(&mutex);

phil_state[i] = THINKING;

test(LEFT);
test(RIGHT);

binsem_up(&mutex);
}

void int_handler(int signo) {
long int duration;
int i;

for (i = 0; i < N; i++) {
duration = ut_get_vtime(tid[i]);
printf("Philosopher (%d) used the CPU %ld.%ld sec.n",
i+1,duration/1000,duration%1000);
}
exit(0);
}

void philosopher(int i){
while (1){
think(i);
take_forks(i);
eat(i);
put_forks(i);
}
}

static int main(int argc, char *argv)
{
int c;
if (argc != 2){
printf("Usage: %s Nn", argv[0]);
exit(1);
}

N = atoi(argv[1]);

if (N < 2){
printf("Usage: %s N (N >=2)n", argv[0]);
exit(1);
}

ut_init(N);
s = (sem_t *)malloc (N * sizeof(sem_t));
phil_state = (int *) malloc (N * sizeof(int));
tid = (int *) malloc (N * sizeof(int));

for (c = 0; c < N ; c++){
phil_state[c] = THINKING;
binsem_init(&(s[c]), 0);
}

for (c = 0; c < N ; c++){
tid[c] = ut_spawn_thread(philosopher,c);
printf("Spawned thread #%dn", tid[c]);
}

binsem_init(&mutex, 1);

signal(SIGINT,int_handler);
ut_start();

return 0; // avoid warnings

}


The makefile also tries to compile these files - ut.c, binsem.c



#include <stdlib.h>
#ifndef _UT_H
#define _UT_H
#include "ut.h"
#include <sys/time.h> // for itimerval
#include <unistd.h> // for alarm
#include <stdlib.h> // for malloc
#include <stdio.h> // for perror
#include <ucontext.h>
# include "ut.h"
#define MAX_TAB_SIZE 128 // the maximal threads table size.
#define MIN_TAB_SIZE 2 // the minimal threads table size.
#define SYS_ERR -1 // system-related failure code
#define TAB_FULL -2 // full threads table failure code
/*This type defines a single slot (entry) in the threads table. Each slot describes a single
thread. Note that we don't need to keep the thread state since every thread is always ready
or running. We also don't have to support adding/stopping thread dynamically, so we also don't
have to manage free slots.*/
typedef struct ut_slot {
ucontext_t uc;
unsigned long vtime; /* the CPU time (in milliseconds) consumed by this thread.*/
void (*func)(int); /* the function executed by the thread.*/
int arg; /* the function argument.*/
} ut_slot_t, *ut_slot;

static ut_slot threads; // pointer to thread table
static volatile int numThreads = 0; // number of threads in the table
static volatile int currentThread = 0; // current thread
static ucontext_t mainThread;


#define STACKSIZE 8192 // the thread stack size.

/* The TID (thread ID) type. TID of a thread is actually the index of the thread in the
threads table. */
typedef short int tid_t;



void handler(int signal){
alarm(1); //the alarm every second as demanded in the assignment
currentThread = (currentThread +1 ) % numThreads;
printf("in signal handler: switching from %d to %dn", currentThread, currentThread - 1);
swapcontext(&threads[currentThread].uc, &threads[currentThread].uc); /*save current thread,
* load next thread*/
if (signal == SIGVTALRM){ // increment the time stats
threads[currentThread].vtime+=100;

} else if(signal==SIGALRM) {
if (swapcontext(&threads[currentThread - 1].uc, &threads[currentThread].uc) == -1) {
perror("could not do swapping");
exit(1);
}
}
}

int ut_init(int tab_size){

/// (###)

if(tab_size < MAX_TAB_SIZE) {
threads = (ut_slot) malloc(tab_size * sizeof(int(ut_slot_t)));
}
else{
threads = (ut_slot) malloc(MAX_TAB_SIZE * sizeof(int(ut_slot_t)));
}
if (!threads) {
return SYS_ERR;
}
return 0;

}

tid_t ut_spawn_thread(void (*func)(int), int arg){
/*uc[1].uc_link = &uc[0];
uc[1].uc_stack.ss_sp = st1; //stack fro thread 1
uc[1].uc_stack.ss_size = sizeof st1; //size of stack for therad
makecontext(&uc[1], (void(*)(void)) f, 1, 1); */
int thread_stack_size = STACKSIZE/8; //no need for 8K in size
if (numThreads>=TAB_FULL){ //(*)
return TAB_FULL;
}
if (getcontext(&threads[numThreads].uc)==-1){
return SYS_ERR;
}
ut_slot_t newThread;
threads[numThreads] = newThread;
threads[numThreads].uc.uc_link = &mainThread;
threads[numThreads].uc.uc_stack.ss_sp = (void* *)malloc(thread_stack_size);

if(threads[numThreads].uc.uc_stack.ss_sp==NULL){
return SYS_ERR;
}
makecontext(&threads[numThreads].uc,(void(*)(void))func,1,arg);
numThreads++;

return numThreads - 1;


}


int ut_start(void){
struct sigaction sigaction1;
int firstThread = 0; /*represents the current thread*/
struct itimerval itv;
/* set up vtimer for accounting */
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 10000;
itv.it_value = itv.it_interval;


/* Initialize the data structures for SIGALRM handling. */
sigaction1.sa_flags = SA_RESTART; //restart instead of throwing exception
sigfillset(&sigaction1.sa_mask); // don't throw exception for additional signals
sigaction1.sa_handler = handler; // specify handler for the sigaction declared

if (sigaction(SIGVTALRM, &sigaction1, NULL) < 0)
return SYS_ERR;
/*START THE TIMER */
if (setitimer(ITIMER_VIRTUAL, &itv, NULL) < 0)
return SYS_ERR;

if (sigaction(SIGINT, &sigaction1, NULL) < 0)
return SYS_ERR;

/* Start running. */

alarm(1); //alarm every second
if(swapcontext(&threads[firstThread].uc,&threads[firstThread+1].uc)==-1){ //swap first time
return SYS_ERR;
}

return -1;
}


unsigned long ut_get_vtime(tid_t tid){
return threads[tid].vtime;
}


#endif


binsem.c



#ifndef _BIN_SEM_H
#define _BIN_SEM_H

#include "binsem.h"
#include <signal.h>
#include "atomic.h"

typedef unsigned long sem_t;

void binsem_init(sem_t *s, int init_val){
if(init_val == 1){
*s = 1;
}
else{
*s = 0;
}
}

void binsem_up(sem_t *s){
xchg(s,1); /*send the pointer of s, and the new value 1*/
}


int binsem_down(sem_t *s){
int flag = 0;
while (flag == 0){
xchg(s,0); /*try changing the value - down*/
if (*s != 0){ /*no success in changing*/
if (raise(SIGALRM)!=0){ /*raise returns 0 on success*/
return -1;
}
} else{
flag = 1;
return 0;
}
}

}

#endif


Any ideas?










share|improve this question
























  • Please edit your code to reduce it to a Minimal, Complete, and Verifiable example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.
    – Toby Speight
    Nov 20 at 11:03










  • Hi, I believe my questions does fit the criteria. I can't minimize it anymore, this is the absolute minimal code needed for running the code.
    – Alan
    Nov 20 at 11:04










  • That is far from the minimum required to reproduce the error. You don't need any variables, or any functions other than main() (and main() can have an empty body).
    – Toby Speight
    Nov 20 at 11:05












  • Seriously, this can be reproduced with a single line source file: static int main(void) {}
    – Toby Speight
    Nov 20 at 11:17
















-2














I have several files which I'm trying to compile using gcc in Ubuntu. I have vmware machine 16.04 ubuntu, which 64-bit computer. I have added the flags for 32bit compilation in the makefile. (-m32 flag).



This is the makefile:



    all: clean binsem.a ut.a ph
FLAGS = -Wall -L./ -m32


ph: ph.c
gcc ${FLAGS} ph.c -lbinsem -lut -o ph


binsem.a:
gcc $(FLAGS) -c binsem.c
ar rcu libbinsem.a binsem.o
ranlib libbinsem.a


ut.a:
gcc $(FLAGS) -c ut.c
ar rcu libut.a ut.o
ranlib libut.a

clean:
rm -f *.o
rm -f a.out
rm -f *~
rm -f ph
rm -f *a


My attempts to compile the code were not successful, as I received the following error:



ph.c:126:12: warning: ‘main’ defined but not used [-Wunused-function]
/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'ph' failed
make: *** [ph] Error 1


**I tried - **




  1. Adding -c flags to the ph.c file in the make file. However it doesn't make much sense, since it has a main function. No success.


    1. Adding sum -m32 flags in the makefile, in addition to what's already written. No Success.




The file "ph.c", is the following file -



#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <inttypes.h>

#include "binsem.h"
#include "ut.h"



#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int N;

volatile int *phil_state;
sem_t *s;
sem_t mutex;
int *tid;

uint64_t get_wall_time() {
struct timeval time;

gettimeofday(&time, NULL);
uint64_t millis = (time.tv_sec * (uint64_t)1000) + (time.tv_usec / 1000);


return millis;
}

void think(int p) {
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;

for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}

printf("Philosopher (%d) - time %" PRId64 " - is hungryn", p, get_wall_time()); fflush (stdout);
}

void eat(int p){
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is eatingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;
for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}
//printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);
}

void test(int i){
if (phil_state[i] == HUNGRY &&
phil_state[LEFT] != EATING &&
phil_state[RIGHT] != EATING){
phil_state[i] = EATING;

binsem_up(&(s[i]));
}
}

void take_forks(int i){
binsem_down(&mutex);

phil_state[i] = HUNGRY;

test(i);

binsem_up(&mutex);

binsem_down(&(s[i]));
}


void put_forks(int i){
binsem_down(&mutex);

phil_state[i] = THINKING;

test(LEFT);
test(RIGHT);

binsem_up(&mutex);
}

void int_handler(int signo) {
long int duration;
int i;

for (i = 0; i < N; i++) {
duration = ut_get_vtime(tid[i]);
printf("Philosopher (%d) used the CPU %ld.%ld sec.n",
i+1,duration/1000,duration%1000);
}
exit(0);
}

void philosopher(int i){
while (1){
think(i);
take_forks(i);
eat(i);
put_forks(i);
}
}

static int main(int argc, char *argv)
{
int c;
if (argc != 2){
printf("Usage: %s Nn", argv[0]);
exit(1);
}

N = atoi(argv[1]);

if (N < 2){
printf("Usage: %s N (N >=2)n", argv[0]);
exit(1);
}

ut_init(N);
s = (sem_t *)malloc (N * sizeof(sem_t));
phil_state = (int *) malloc (N * sizeof(int));
tid = (int *) malloc (N * sizeof(int));

for (c = 0; c < N ; c++){
phil_state[c] = THINKING;
binsem_init(&(s[c]), 0);
}

for (c = 0; c < N ; c++){
tid[c] = ut_spawn_thread(philosopher,c);
printf("Spawned thread #%dn", tid[c]);
}

binsem_init(&mutex, 1);

signal(SIGINT,int_handler);
ut_start();

return 0; // avoid warnings

}


The makefile also tries to compile these files - ut.c, binsem.c



#include <stdlib.h>
#ifndef _UT_H
#define _UT_H
#include "ut.h"
#include <sys/time.h> // for itimerval
#include <unistd.h> // for alarm
#include <stdlib.h> // for malloc
#include <stdio.h> // for perror
#include <ucontext.h>
# include "ut.h"
#define MAX_TAB_SIZE 128 // the maximal threads table size.
#define MIN_TAB_SIZE 2 // the minimal threads table size.
#define SYS_ERR -1 // system-related failure code
#define TAB_FULL -2 // full threads table failure code
/*This type defines a single slot (entry) in the threads table. Each slot describes a single
thread. Note that we don't need to keep the thread state since every thread is always ready
or running. We also don't have to support adding/stopping thread dynamically, so we also don't
have to manage free slots.*/
typedef struct ut_slot {
ucontext_t uc;
unsigned long vtime; /* the CPU time (in milliseconds) consumed by this thread.*/
void (*func)(int); /* the function executed by the thread.*/
int arg; /* the function argument.*/
} ut_slot_t, *ut_slot;

static ut_slot threads; // pointer to thread table
static volatile int numThreads = 0; // number of threads in the table
static volatile int currentThread = 0; // current thread
static ucontext_t mainThread;


#define STACKSIZE 8192 // the thread stack size.

/* The TID (thread ID) type. TID of a thread is actually the index of the thread in the
threads table. */
typedef short int tid_t;



void handler(int signal){
alarm(1); //the alarm every second as demanded in the assignment
currentThread = (currentThread +1 ) % numThreads;
printf("in signal handler: switching from %d to %dn", currentThread, currentThread - 1);
swapcontext(&threads[currentThread].uc, &threads[currentThread].uc); /*save current thread,
* load next thread*/
if (signal == SIGVTALRM){ // increment the time stats
threads[currentThread].vtime+=100;

} else if(signal==SIGALRM) {
if (swapcontext(&threads[currentThread - 1].uc, &threads[currentThread].uc) == -1) {
perror("could not do swapping");
exit(1);
}
}
}

int ut_init(int tab_size){

/// (###)

if(tab_size < MAX_TAB_SIZE) {
threads = (ut_slot) malloc(tab_size * sizeof(int(ut_slot_t)));
}
else{
threads = (ut_slot) malloc(MAX_TAB_SIZE * sizeof(int(ut_slot_t)));
}
if (!threads) {
return SYS_ERR;
}
return 0;

}

tid_t ut_spawn_thread(void (*func)(int), int arg){
/*uc[1].uc_link = &uc[0];
uc[1].uc_stack.ss_sp = st1; //stack fro thread 1
uc[1].uc_stack.ss_size = sizeof st1; //size of stack for therad
makecontext(&uc[1], (void(*)(void)) f, 1, 1); */
int thread_stack_size = STACKSIZE/8; //no need for 8K in size
if (numThreads>=TAB_FULL){ //(*)
return TAB_FULL;
}
if (getcontext(&threads[numThreads].uc)==-1){
return SYS_ERR;
}
ut_slot_t newThread;
threads[numThreads] = newThread;
threads[numThreads].uc.uc_link = &mainThread;
threads[numThreads].uc.uc_stack.ss_sp = (void* *)malloc(thread_stack_size);

if(threads[numThreads].uc.uc_stack.ss_sp==NULL){
return SYS_ERR;
}
makecontext(&threads[numThreads].uc,(void(*)(void))func,1,arg);
numThreads++;

return numThreads - 1;


}


int ut_start(void){
struct sigaction sigaction1;
int firstThread = 0; /*represents the current thread*/
struct itimerval itv;
/* set up vtimer for accounting */
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 10000;
itv.it_value = itv.it_interval;


/* Initialize the data structures for SIGALRM handling. */
sigaction1.sa_flags = SA_RESTART; //restart instead of throwing exception
sigfillset(&sigaction1.sa_mask); // don't throw exception for additional signals
sigaction1.sa_handler = handler; // specify handler for the sigaction declared

if (sigaction(SIGVTALRM, &sigaction1, NULL) < 0)
return SYS_ERR;
/*START THE TIMER */
if (setitimer(ITIMER_VIRTUAL, &itv, NULL) < 0)
return SYS_ERR;

if (sigaction(SIGINT, &sigaction1, NULL) < 0)
return SYS_ERR;

/* Start running. */

alarm(1); //alarm every second
if(swapcontext(&threads[firstThread].uc,&threads[firstThread+1].uc)==-1){ //swap first time
return SYS_ERR;
}

return -1;
}


unsigned long ut_get_vtime(tid_t tid){
return threads[tid].vtime;
}


#endif


binsem.c



#ifndef _BIN_SEM_H
#define _BIN_SEM_H

#include "binsem.h"
#include <signal.h>
#include "atomic.h"

typedef unsigned long sem_t;

void binsem_init(sem_t *s, int init_val){
if(init_val == 1){
*s = 1;
}
else{
*s = 0;
}
}

void binsem_up(sem_t *s){
xchg(s,1); /*send the pointer of s, and the new value 1*/
}


int binsem_down(sem_t *s){
int flag = 0;
while (flag == 0){
xchg(s,0); /*try changing the value - down*/
if (*s != 0){ /*no success in changing*/
if (raise(SIGALRM)!=0){ /*raise returns 0 on success*/
return -1;
}
} else{
flag = 1;
return 0;
}
}

}

#endif


Any ideas?










share|improve this question
























  • Please edit your code to reduce it to a Minimal, Complete, and Verifiable example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.
    – Toby Speight
    Nov 20 at 11:03










  • Hi, I believe my questions does fit the criteria. I can't minimize it anymore, this is the absolute minimal code needed for running the code.
    – Alan
    Nov 20 at 11:04










  • That is far from the minimum required to reproduce the error. You don't need any variables, or any functions other than main() (and main() can have an empty body).
    – Toby Speight
    Nov 20 at 11:05












  • Seriously, this can be reproduced with a single line source file: static int main(void) {}
    – Toby Speight
    Nov 20 at 11:17














-2












-2








-2







I have several files which I'm trying to compile using gcc in Ubuntu. I have vmware machine 16.04 ubuntu, which 64-bit computer. I have added the flags for 32bit compilation in the makefile. (-m32 flag).



This is the makefile:



    all: clean binsem.a ut.a ph
FLAGS = -Wall -L./ -m32


ph: ph.c
gcc ${FLAGS} ph.c -lbinsem -lut -o ph


binsem.a:
gcc $(FLAGS) -c binsem.c
ar rcu libbinsem.a binsem.o
ranlib libbinsem.a


ut.a:
gcc $(FLAGS) -c ut.c
ar rcu libut.a ut.o
ranlib libut.a

clean:
rm -f *.o
rm -f a.out
rm -f *~
rm -f ph
rm -f *a


My attempts to compile the code were not successful, as I received the following error:



ph.c:126:12: warning: ‘main’ defined but not used [-Wunused-function]
/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'ph' failed
make: *** [ph] Error 1


**I tried - **




  1. Adding -c flags to the ph.c file in the make file. However it doesn't make much sense, since it has a main function. No success.


    1. Adding sum -m32 flags in the makefile, in addition to what's already written. No Success.




The file "ph.c", is the following file -



#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <inttypes.h>

#include "binsem.h"
#include "ut.h"



#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int N;

volatile int *phil_state;
sem_t *s;
sem_t mutex;
int *tid;

uint64_t get_wall_time() {
struct timeval time;

gettimeofday(&time, NULL);
uint64_t millis = (time.tv_sec * (uint64_t)1000) + (time.tv_usec / 1000);


return millis;
}

void think(int p) {
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;

for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}

printf("Philosopher (%d) - time %" PRId64 " - is hungryn", p, get_wall_time()); fflush (stdout);
}

void eat(int p){
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is eatingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;
for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}
//printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);
}

void test(int i){
if (phil_state[i] == HUNGRY &&
phil_state[LEFT] != EATING &&
phil_state[RIGHT] != EATING){
phil_state[i] = EATING;

binsem_up(&(s[i]));
}
}

void take_forks(int i){
binsem_down(&mutex);

phil_state[i] = HUNGRY;

test(i);

binsem_up(&mutex);

binsem_down(&(s[i]));
}


void put_forks(int i){
binsem_down(&mutex);

phil_state[i] = THINKING;

test(LEFT);
test(RIGHT);

binsem_up(&mutex);
}

void int_handler(int signo) {
long int duration;
int i;

for (i = 0; i < N; i++) {
duration = ut_get_vtime(tid[i]);
printf("Philosopher (%d) used the CPU %ld.%ld sec.n",
i+1,duration/1000,duration%1000);
}
exit(0);
}

void philosopher(int i){
while (1){
think(i);
take_forks(i);
eat(i);
put_forks(i);
}
}

static int main(int argc, char *argv)
{
int c;
if (argc != 2){
printf("Usage: %s Nn", argv[0]);
exit(1);
}

N = atoi(argv[1]);

if (N < 2){
printf("Usage: %s N (N >=2)n", argv[0]);
exit(1);
}

ut_init(N);
s = (sem_t *)malloc (N * sizeof(sem_t));
phil_state = (int *) malloc (N * sizeof(int));
tid = (int *) malloc (N * sizeof(int));

for (c = 0; c < N ; c++){
phil_state[c] = THINKING;
binsem_init(&(s[c]), 0);
}

for (c = 0; c < N ; c++){
tid[c] = ut_spawn_thread(philosopher,c);
printf("Spawned thread #%dn", tid[c]);
}

binsem_init(&mutex, 1);

signal(SIGINT,int_handler);
ut_start();

return 0; // avoid warnings

}


The makefile also tries to compile these files - ut.c, binsem.c



#include <stdlib.h>
#ifndef _UT_H
#define _UT_H
#include "ut.h"
#include <sys/time.h> // for itimerval
#include <unistd.h> // for alarm
#include <stdlib.h> // for malloc
#include <stdio.h> // for perror
#include <ucontext.h>
# include "ut.h"
#define MAX_TAB_SIZE 128 // the maximal threads table size.
#define MIN_TAB_SIZE 2 // the minimal threads table size.
#define SYS_ERR -1 // system-related failure code
#define TAB_FULL -2 // full threads table failure code
/*This type defines a single slot (entry) in the threads table. Each slot describes a single
thread. Note that we don't need to keep the thread state since every thread is always ready
or running. We also don't have to support adding/stopping thread dynamically, so we also don't
have to manage free slots.*/
typedef struct ut_slot {
ucontext_t uc;
unsigned long vtime; /* the CPU time (in milliseconds) consumed by this thread.*/
void (*func)(int); /* the function executed by the thread.*/
int arg; /* the function argument.*/
} ut_slot_t, *ut_slot;

static ut_slot threads; // pointer to thread table
static volatile int numThreads = 0; // number of threads in the table
static volatile int currentThread = 0; // current thread
static ucontext_t mainThread;


#define STACKSIZE 8192 // the thread stack size.

/* The TID (thread ID) type. TID of a thread is actually the index of the thread in the
threads table. */
typedef short int tid_t;



void handler(int signal){
alarm(1); //the alarm every second as demanded in the assignment
currentThread = (currentThread +1 ) % numThreads;
printf("in signal handler: switching from %d to %dn", currentThread, currentThread - 1);
swapcontext(&threads[currentThread].uc, &threads[currentThread].uc); /*save current thread,
* load next thread*/
if (signal == SIGVTALRM){ // increment the time stats
threads[currentThread].vtime+=100;

} else if(signal==SIGALRM) {
if (swapcontext(&threads[currentThread - 1].uc, &threads[currentThread].uc) == -1) {
perror("could not do swapping");
exit(1);
}
}
}

int ut_init(int tab_size){

/// (###)

if(tab_size < MAX_TAB_SIZE) {
threads = (ut_slot) malloc(tab_size * sizeof(int(ut_slot_t)));
}
else{
threads = (ut_slot) malloc(MAX_TAB_SIZE * sizeof(int(ut_slot_t)));
}
if (!threads) {
return SYS_ERR;
}
return 0;

}

tid_t ut_spawn_thread(void (*func)(int), int arg){
/*uc[1].uc_link = &uc[0];
uc[1].uc_stack.ss_sp = st1; //stack fro thread 1
uc[1].uc_stack.ss_size = sizeof st1; //size of stack for therad
makecontext(&uc[1], (void(*)(void)) f, 1, 1); */
int thread_stack_size = STACKSIZE/8; //no need for 8K in size
if (numThreads>=TAB_FULL){ //(*)
return TAB_FULL;
}
if (getcontext(&threads[numThreads].uc)==-1){
return SYS_ERR;
}
ut_slot_t newThread;
threads[numThreads] = newThread;
threads[numThreads].uc.uc_link = &mainThread;
threads[numThreads].uc.uc_stack.ss_sp = (void* *)malloc(thread_stack_size);

if(threads[numThreads].uc.uc_stack.ss_sp==NULL){
return SYS_ERR;
}
makecontext(&threads[numThreads].uc,(void(*)(void))func,1,arg);
numThreads++;

return numThreads - 1;


}


int ut_start(void){
struct sigaction sigaction1;
int firstThread = 0; /*represents the current thread*/
struct itimerval itv;
/* set up vtimer for accounting */
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 10000;
itv.it_value = itv.it_interval;


/* Initialize the data structures for SIGALRM handling. */
sigaction1.sa_flags = SA_RESTART; //restart instead of throwing exception
sigfillset(&sigaction1.sa_mask); // don't throw exception for additional signals
sigaction1.sa_handler = handler; // specify handler for the sigaction declared

if (sigaction(SIGVTALRM, &sigaction1, NULL) < 0)
return SYS_ERR;
/*START THE TIMER */
if (setitimer(ITIMER_VIRTUAL, &itv, NULL) < 0)
return SYS_ERR;

if (sigaction(SIGINT, &sigaction1, NULL) < 0)
return SYS_ERR;

/* Start running. */

alarm(1); //alarm every second
if(swapcontext(&threads[firstThread].uc,&threads[firstThread+1].uc)==-1){ //swap first time
return SYS_ERR;
}

return -1;
}


unsigned long ut_get_vtime(tid_t tid){
return threads[tid].vtime;
}


#endif


binsem.c



#ifndef _BIN_SEM_H
#define _BIN_SEM_H

#include "binsem.h"
#include <signal.h>
#include "atomic.h"

typedef unsigned long sem_t;

void binsem_init(sem_t *s, int init_val){
if(init_val == 1){
*s = 1;
}
else{
*s = 0;
}
}

void binsem_up(sem_t *s){
xchg(s,1); /*send the pointer of s, and the new value 1*/
}


int binsem_down(sem_t *s){
int flag = 0;
while (flag == 0){
xchg(s,0); /*try changing the value - down*/
if (*s != 0){ /*no success in changing*/
if (raise(SIGALRM)!=0){ /*raise returns 0 on success*/
return -1;
}
} else{
flag = 1;
return 0;
}
}

}

#endif


Any ideas?










share|improve this question















I have several files which I'm trying to compile using gcc in Ubuntu. I have vmware machine 16.04 ubuntu, which 64-bit computer. I have added the flags for 32bit compilation in the makefile. (-m32 flag).



This is the makefile:



    all: clean binsem.a ut.a ph
FLAGS = -Wall -L./ -m32


ph: ph.c
gcc ${FLAGS} ph.c -lbinsem -lut -o ph


binsem.a:
gcc $(FLAGS) -c binsem.c
ar rcu libbinsem.a binsem.o
ranlib libbinsem.a


ut.a:
gcc $(FLAGS) -c ut.c
ar rcu libut.a ut.o
ranlib libut.a

clean:
rm -f *.o
rm -f a.out
rm -f *~
rm -f ph
rm -f *a


My attempts to compile the code were not successful, as I received the following error:



ph.c:126:12: warning: ‘main’ defined but not used [-Wunused-function]
/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'ph' failed
make: *** [ph] Error 1


**I tried - **




  1. Adding -c flags to the ph.c file in the make file. However it doesn't make much sense, since it has a main function. No success.


    1. Adding sum -m32 flags in the makefile, in addition to what's already written. No Success.




The file "ph.c", is the following file -



#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <inttypes.h>

#include "binsem.h"
#include "ut.h"



#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int N;

volatile int *phil_state;
sem_t *s;
sem_t mutex;
int *tid;

uint64_t get_wall_time() {
struct timeval time;

gettimeofday(&time, NULL);
uint64_t millis = (time.tv_sec * (uint64_t)1000) + (time.tv_usec / 1000);


return millis;
}

void think(int p) {
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;

for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}

printf("Philosopher (%d) - time %" PRId64 " - is hungryn", p, get_wall_time()); fflush (stdout);
}

void eat(int p){
int i, factor;
volatile int j;

printf("Philosopher (%d) - time %" PRId64 " - is eatingn",p, get_wall_time()); fflush (stdout);

factor = 1 + random()%5;
for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}
//printf("Philosopher (%d) - time %" PRId64 " - is thinkingn",p, get_wall_time()); fflush (stdout);
}

void test(int i){
if (phil_state[i] == HUNGRY &&
phil_state[LEFT] != EATING &&
phil_state[RIGHT] != EATING){
phil_state[i] = EATING;

binsem_up(&(s[i]));
}
}

void take_forks(int i){
binsem_down(&mutex);

phil_state[i] = HUNGRY;

test(i);

binsem_up(&mutex);

binsem_down(&(s[i]));
}


void put_forks(int i){
binsem_down(&mutex);

phil_state[i] = THINKING;

test(LEFT);
test(RIGHT);

binsem_up(&mutex);
}

void int_handler(int signo) {
long int duration;
int i;

for (i = 0; i < N; i++) {
duration = ut_get_vtime(tid[i]);
printf("Philosopher (%d) used the CPU %ld.%ld sec.n",
i+1,duration/1000,duration%1000);
}
exit(0);
}

void philosopher(int i){
while (1){
think(i);
take_forks(i);
eat(i);
put_forks(i);
}
}

static int main(int argc, char *argv)
{
int c;
if (argc != 2){
printf("Usage: %s Nn", argv[0]);
exit(1);
}

N = atoi(argv[1]);

if (N < 2){
printf("Usage: %s N (N >=2)n", argv[0]);
exit(1);
}

ut_init(N);
s = (sem_t *)malloc (N * sizeof(sem_t));
phil_state = (int *) malloc (N * sizeof(int));
tid = (int *) malloc (N * sizeof(int));

for (c = 0; c < N ; c++){
phil_state[c] = THINKING;
binsem_init(&(s[c]), 0);
}

for (c = 0; c < N ; c++){
tid[c] = ut_spawn_thread(philosopher,c);
printf("Spawned thread #%dn", tid[c]);
}

binsem_init(&mutex, 1);

signal(SIGINT,int_handler);
ut_start();

return 0; // avoid warnings

}


The makefile also tries to compile these files - ut.c, binsem.c



#include <stdlib.h>
#ifndef _UT_H
#define _UT_H
#include "ut.h"
#include <sys/time.h> // for itimerval
#include <unistd.h> // for alarm
#include <stdlib.h> // for malloc
#include <stdio.h> // for perror
#include <ucontext.h>
# include "ut.h"
#define MAX_TAB_SIZE 128 // the maximal threads table size.
#define MIN_TAB_SIZE 2 // the minimal threads table size.
#define SYS_ERR -1 // system-related failure code
#define TAB_FULL -2 // full threads table failure code
/*This type defines a single slot (entry) in the threads table. Each slot describes a single
thread. Note that we don't need to keep the thread state since every thread is always ready
or running. We also don't have to support adding/stopping thread dynamically, so we also don't
have to manage free slots.*/
typedef struct ut_slot {
ucontext_t uc;
unsigned long vtime; /* the CPU time (in milliseconds) consumed by this thread.*/
void (*func)(int); /* the function executed by the thread.*/
int arg; /* the function argument.*/
} ut_slot_t, *ut_slot;

static ut_slot threads; // pointer to thread table
static volatile int numThreads = 0; // number of threads in the table
static volatile int currentThread = 0; // current thread
static ucontext_t mainThread;


#define STACKSIZE 8192 // the thread stack size.

/* The TID (thread ID) type. TID of a thread is actually the index of the thread in the
threads table. */
typedef short int tid_t;



void handler(int signal){
alarm(1); //the alarm every second as demanded in the assignment
currentThread = (currentThread +1 ) % numThreads;
printf("in signal handler: switching from %d to %dn", currentThread, currentThread - 1);
swapcontext(&threads[currentThread].uc, &threads[currentThread].uc); /*save current thread,
* load next thread*/
if (signal == SIGVTALRM){ // increment the time stats
threads[currentThread].vtime+=100;

} else if(signal==SIGALRM) {
if (swapcontext(&threads[currentThread - 1].uc, &threads[currentThread].uc) == -1) {
perror("could not do swapping");
exit(1);
}
}
}

int ut_init(int tab_size){

/// (###)

if(tab_size < MAX_TAB_SIZE) {
threads = (ut_slot) malloc(tab_size * sizeof(int(ut_slot_t)));
}
else{
threads = (ut_slot) malloc(MAX_TAB_SIZE * sizeof(int(ut_slot_t)));
}
if (!threads) {
return SYS_ERR;
}
return 0;

}

tid_t ut_spawn_thread(void (*func)(int), int arg){
/*uc[1].uc_link = &uc[0];
uc[1].uc_stack.ss_sp = st1; //stack fro thread 1
uc[1].uc_stack.ss_size = sizeof st1; //size of stack for therad
makecontext(&uc[1], (void(*)(void)) f, 1, 1); */
int thread_stack_size = STACKSIZE/8; //no need for 8K in size
if (numThreads>=TAB_FULL){ //(*)
return TAB_FULL;
}
if (getcontext(&threads[numThreads].uc)==-1){
return SYS_ERR;
}
ut_slot_t newThread;
threads[numThreads] = newThread;
threads[numThreads].uc.uc_link = &mainThread;
threads[numThreads].uc.uc_stack.ss_sp = (void* *)malloc(thread_stack_size);

if(threads[numThreads].uc.uc_stack.ss_sp==NULL){
return SYS_ERR;
}
makecontext(&threads[numThreads].uc,(void(*)(void))func,1,arg);
numThreads++;

return numThreads - 1;


}


int ut_start(void){
struct sigaction sigaction1;
int firstThread = 0; /*represents the current thread*/
struct itimerval itv;
/* set up vtimer for accounting */
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 10000;
itv.it_value = itv.it_interval;


/* Initialize the data structures for SIGALRM handling. */
sigaction1.sa_flags = SA_RESTART; //restart instead of throwing exception
sigfillset(&sigaction1.sa_mask); // don't throw exception for additional signals
sigaction1.sa_handler = handler; // specify handler for the sigaction declared

if (sigaction(SIGVTALRM, &sigaction1, NULL) < 0)
return SYS_ERR;
/*START THE TIMER */
if (setitimer(ITIMER_VIRTUAL, &itv, NULL) < 0)
return SYS_ERR;

if (sigaction(SIGINT, &sigaction1, NULL) < 0)
return SYS_ERR;

/* Start running. */

alarm(1); //alarm every second
if(swapcontext(&threads[firstThread].uc,&threads[firstThread+1].uc)==-1){ //swap first time
return SYS_ERR;
}

return -1;
}


unsigned long ut_get_vtime(tid_t tid){
return threads[tid].vtime;
}


#endif


binsem.c



#ifndef _BIN_SEM_H
#define _BIN_SEM_H

#include "binsem.h"
#include <signal.h>
#include "atomic.h"

typedef unsigned long sem_t;

void binsem_init(sem_t *s, int init_val){
if(init_val == 1){
*s = 1;
}
else{
*s = 0;
}
}

void binsem_up(sem_t *s){
xchg(s,1); /*send the pointer of s, and the new value 1*/
}


int binsem_down(sem_t *s){
int flag = 0;
while (flag == 0){
xchg(s,0); /*try changing the value - down*/
if (*s != 0){ /*no success in changing*/
if (raise(SIGALRM)!=0){ /*raise returns 0 on success*/
return -1;
}
} else{
flag = 1;
return 0;
}
}

}

#endif


Any ideas?







c linux ubuntu gcc makefile






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 10:55









P.W

10.9k3742




10.9k3742










asked Nov 20 at 10:49









Alan

5282620




5282620












  • Please edit your code to reduce it to a Minimal, Complete, and Verifiable example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.
    – Toby Speight
    Nov 20 at 11:03










  • Hi, I believe my questions does fit the criteria. I can't minimize it anymore, this is the absolute minimal code needed for running the code.
    – Alan
    Nov 20 at 11:04










  • That is far from the minimum required to reproduce the error. You don't need any variables, or any functions other than main() (and main() can have an empty body).
    – Toby Speight
    Nov 20 at 11:05












  • Seriously, this can be reproduced with a single line source file: static int main(void) {}
    – Toby Speight
    Nov 20 at 11:17


















  • Please edit your code to reduce it to a Minimal, Complete, and Verifiable example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.
    – Toby Speight
    Nov 20 at 11:03










  • Hi, I believe my questions does fit the criteria. I can't minimize it anymore, this is the absolute minimal code needed for running the code.
    – Alan
    Nov 20 at 11:04










  • That is far from the minimum required to reproduce the error. You don't need any variables, or any functions other than main() (and main() can have an empty body).
    – Toby Speight
    Nov 20 at 11:05












  • Seriously, this can be reproduced with a single line source file: static int main(void) {}
    – Toby Speight
    Nov 20 at 11:17
















Please edit your code to reduce it to a Minimal, Complete, and Verifiable example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.
– Toby Speight
Nov 20 at 11:03




Please edit your code to reduce it to a Minimal, Complete, and Verifiable example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.
– Toby Speight
Nov 20 at 11:03












Hi, I believe my questions does fit the criteria. I can't minimize it anymore, this is the absolute minimal code needed for running the code.
– Alan
Nov 20 at 11:04




Hi, I believe my questions does fit the criteria. I can't minimize it anymore, this is the absolute minimal code needed for running the code.
– Alan
Nov 20 at 11:04












That is far from the minimum required to reproduce the error. You don't need any variables, or any functions other than main() (and main() can have an empty body).
– Toby Speight
Nov 20 at 11:05






That is far from the minimum required to reproduce the error. You don't need any variables, or any functions other than main() (and main() can have an empty body).
– Toby Speight
Nov 20 at 11:05














Seriously, this can be reproduced with a single line source file: static int main(void) {}
– Toby Speight
Nov 20 at 11:17




Seriously, this can be reproduced with a single line source file: static int main(void) {}
– Toby Speight
Nov 20 at 11:17












2 Answers
2






active

oldest

votes


















2














You declare the main function to be static. That means it will have internal linkage, and not be exported. Therefore the linker will not be able to find it.



Remove the static modifier and that should work.





However there are also many other problems in your Makefile that will most likely lead to problems:



The target ph only depends on ph.c, not the libraries you want to link with. You need to add the libraries as dependencies as well (their full file-names).



You should also make the libraries depend on the object files used to create them, and rely on the implicit rules to build object files from source files.



Also note that for a library named A then the file-name needs to be libA.a, otherwise the linker will not be able to find it with the -l (lower-case L) option.






share|improve this answer































    2














    The error message is pretty clear:




    (.text+0x18): undefined reference to `main'



    In ph.c you have (probably accustomed from Java?):



    static int main(int argc, char *argv)


    In C:




    1. static ([CPPReference]: C keywords: static) means internal linkage (only valid in current translation unit (ph.o in our case)), so a static symbol won't be "seen" by the linker (loader)


    2. Code linked to an application (not a dynamic library or shared object (.so: linked with -shared)), must explicitly define main, and that should be visible by the linker



    The combination of the above 2, lead to what you're experiencing.



    Remove the static and you'll be fine.



    Note: there might be other errors in the makefile.






    share|improve this answer























    • Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
      – Alan
      Nov 20 at 11:02






    • 1




      @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
      – Some programmer dude
      Nov 20 at 11:07










    • @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
      – Alan
      Nov 20 at 11:15










    • Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
      – CristiFati
      Nov 20 at 11:22













    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391352%2ffailing-to-execute-make-in-ubuntu-gcc%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    You declare the main function to be static. That means it will have internal linkage, and not be exported. Therefore the linker will not be able to find it.



    Remove the static modifier and that should work.





    However there are also many other problems in your Makefile that will most likely lead to problems:



    The target ph only depends on ph.c, not the libraries you want to link with. You need to add the libraries as dependencies as well (their full file-names).



    You should also make the libraries depend on the object files used to create them, and rely on the implicit rules to build object files from source files.



    Also note that for a library named A then the file-name needs to be libA.a, otherwise the linker will not be able to find it with the -l (lower-case L) option.






    share|improve this answer




























      2














      You declare the main function to be static. That means it will have internal linkage, and not be exported. Therefore the linker will not be able to find it.



      Remove the static modifier and that should work.





      However there are also many other problems in your Makefile that will most likely lead to problems:



      The target ph only depends on ph.c, not the libraries you want to link with. You need to add the libraries as dependencies as well (their full file-names).



      You should also make the libraries depend on the object files used to create them, and rely on the implicit rules to build object files from source files.



      Also note that for a library named A then the file-name needs to be libA.a, otherwise the linker will not be able to find it with the -l (lower-case L) option.






      share|improve this answer


























        2












        2








        2






        You declare the main function to be static. That means it will have internal linkage, and not be exported. Therefore the linker will not be able to find it.



        Remove the static modifier and that should work.





        However there are also many other problems in your Makefile that will most likely lead to problems:



        The target ph only depends on ph.c, not the libraries you want to link with. You need to add the libraries as dependencies as well (their full file-names).



        You should also make the libraries depend on the object files used to create them, and rely on the implicit rules to build object files from source files.



        Also note that for a library named A then the file-name needs to be libA.a, otherwise the linker will not be able to find it with the -l (lower-case L) option.






        share|improve this answer














        You declare the main function to be static. That means it will have internal linkage, and not be exported. Therefore the linker will not be able to find it.



        Remove the static modifier and that should work.





        However there are also many other problems in your Makefile that will most likely lead to problems:



        The target ph only depends on ph.c, not the libraries you want to link with. You need to add the libraries as dependencies as well (their full file-names).



        You should also make the libraries depend on the object files used to create them, and rely on the implicit rules to build object files from source files.



        Also note that for a library named A then the file-name needs to be libA.a, otherwise the linker will not be able to find it with the -l (lower-case L) option.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 20 at 11:04









        Toby Speight

        16.2k133965




        16.2k133965










        answered Nov 20 at 10:53









        Some programmer dude

        293k24245404




        293k24245404

























            2














            The error message is pretty clear:




            (.text+0x18): undefined reference to `main'



            In ph.c you have (probably accustomed from Java?):



            static int main(int argc, char *argv)


            In C:




            1. static ([CPPReference]: C keywords: static) means internal linkage (only valid in current translation unit (ph.o in our case)), so a static symbol won't be "seen" by the linker (loader)


            2. Code linked to an application (not a dynamic library or shared object (.so: linked with -shared)), must explicitly define main, and that should be visible by the linker



            The combination of the above 2, lead to what you're experiencing.



            Remove the static and you'll be fine.



            Note: there might be other errors in the makefile.






            share|improve this answer























            • Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
              – Alan
              Nov 20 at 11:02






            • 1




              @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
              – Some programmer dude
              Nov 20 at 11:07










            • @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
              – Alan
              Nov 20 at 11:15










            • Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
              – CristiFati
              Nov 20 at 11:22


















            2














            The error message is pretty clear:




            (.text+0x18): undefined reference to `main'



            In ph.c you have (probably accustomed from Java?):



            static int main(int argc, char *argv)


            In C:




            1. static ([CPPReference]: C keywords: static) means internal linkage (only valid in current translation unit (ph.o in our case)), so a static symbol won't be "seen" by the linker (loader)


            2. Code linked to an application (not a dynamic library or shared object (.so: linked with -shared)), must explicitly define main, and that should be visible by the linker



            The combination of the above 2, lead to what you're experiencing.



            Remove the static and you'll be fine.



            Note: there might be other errors in the makefile.






            share|improve this answer























            • Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
              – Alan
              Nov 20 at 11:02






            • 1




              @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
              – Some programmer dude
              Nov 20 at 11:07










            • @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
              – Alan
              Nov 20 at 11:15










            • Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
              – CristiFati
              Nov 20 at 11:22
















            2












            2








            2






            The error message is pretty clear:




            (.text+0x18): undefined reference to `main'



            In ph.c you have (probably accustomed from Java?):



            static int main(int argc, char *argv)


            In C:




            1. static ([CPPReference]: C keywords: static) means internal linkage (only valid in current translation unit (ph.o in our case)), so a static symbol won't be "seen" by the linker (loader)


            2. Code linked to an application (not a dynamic library or shared object (.so: linked with -shared)), must explicitly define main, and that should be visible by the linker



            The combination of the above 2, lead to what you're experiencing.



            Remove the static and you'll be fine.



            Note: there might be other errors in the makefile.






            share|improve this answer














            The error message is pretty clear:




            (.text+0x18): undefined reference to `main'



            In ph.c you have (probably accustomed from Java?):



            static int main(int argc, char *argv)


            In C:




            1. static ([CPPReference]: C keywords: static) means internal linkage (only valid in current translation unit (ph.o in our case)), so a static symbol won't be "seen" by the linker (loader)


            2. Code linked to an application (not a dynamic library or shared object (.so: linked with -shared)), must explicitly define main, and that should be visible by the linker



            The combination of the above 2, lead to what you're experiencing.



            Remove the static and you'll be fine.



            Note: there might be other errors in the makefile.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 at 11:28

























            answered Nov 20 at 10:57









            CristiFati

            11.4k72135




            11.4k72135












            • Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
              – Alan
              Nov 20 at 11:02






            • 1




              @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
              – Some programmer dude
              Nov 20 at 11:07










            • @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
              – Alan
              Nov 20 at 11:15










            • Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
              – CristiFati
              Nov 20 at 11:22




















            • Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
              – Alan
              Nov 20 at 11:02






            • 1




              @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
              – Some programmer dude
              Nov 20 at 11:07










            • @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
              – Alan
              Nov 20 at 11:15










            • Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
              – CristiFati
              Nov 20 at 11:22


















            Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
            – Alan
            Nov 20 at 11:02




            Hi, thank you! Can you please explain why does it make problems? Can I fix the problem, without removing the "static"?
            – Alan
            Nov 20 at 11:02




            1




            1




            @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
            – Some programmer dude
            Nov 20 at 11:07




            @Alan Why do you need internal linkage for the main function? What is the problem using static is meant to solve? And no you're not supposed to use any modifier or qualifier for the main function.
            – Some programmer dude
            Nov 20 at 11:07












            @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
            – Alan
            Nov 20 at 11:15




            @Someprogrammerdude actually I'm not sure. I was supposed to write two libraries to use this main function (ut.c, binsem.c).
            – Alan
            Nov 20 at 11:15












            Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
            – CristiFati
            Nov 20 at 11:22






            Then you could move main to binsem.c (and fix the errors that this action would trigger, as I can see it references some global variables), and still remove static.
            – CristiFati
            Nov 20 at 11:22




















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391352%2ffailing-to-execute-make-in-ubuntu-gcc%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Ottavio Pratesi

            Tricia Helfer

            15 giugno