无法在Ubuntu gcc中执行“ make”

时间:2018-11-20 10:49:28

标签: c linux ubuntu gcc makefile

我有几个文件正在尝试在Ubuntu中使用gcc进行编译。我有vmware机器16.04 ubuntu,它是64位计算机。我在makefile中添加了用于32位编译的标志。 (-m32标志)。

这是makefile:

request": "GET https://www.vvvvvvv HTTP/2.0""
http_method": "GET"

我尝试编译代码失败,因为我收到以下错误:

    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 

**我尝试过-**

  1. 在make文件的ph.c文件中添加-c标志。但是,由于它具有主要功能,因此意义不大。没有成功
    1. 除了已编写的内容外,还在makefile中添加sum -m32标志。没有成功。

文件“ ph.c”是以下文件-

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

makefile还会尝试编译这些文件-#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 thinking\n",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 hungry\n", p, get_wall_time()); fflush (stdout); } void eat(int p){ int i, factor; volatile int j; printf("Philosopher (%d) - time %" PRId64 " - is eating\n",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 thinking\n",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 N\n", 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 #%d\n", tid[c]); } binsem_init(&mutex, 1); signal(SIGINT,int_handler); ut_start(); return 0; // avoid warnings } ut.c

binsem.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 %d\n", 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

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您将main函数声明为static。这意味着它将具有 内部 linkage,并且不会导出。因此,链接器将无法找到它。

删除static修饰符,应该可以。


不过,您的Makefile中还有许多其他问题很可能会导致问题:

目标ph 取决于ph.c,而不取决于您要链接的库。您还需要添加库作为依赖项(它们的完整文件名)。

还应该使库依赖于用于创建它们的目标文件,并依赖隐式规则从源文件构建目标文件。

还要注意,对于名为A的库,文件名必须为libA.a,否则链接器将无法使用-l找到它(小写) L)选项。

答案 1 :(得分:2)

错误消息很清楚:

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

ph.c 中(可能是 Java 习惯的?):

static int main(int argc, char *argv[])

C 中:

  1. 静态[CPPReference]: C keywords: static)表示内部链接(仅在当前的翻译单元 ph .o )),因此 linker loader )不会“看到” static 符号

  2. 链接到应用程序(不是动态库共享对象 .so :与{{1} })),必须显式定义 main ,并且 linker

  3. 应该可见

上述2种方法的结合会带来您所遇到的问题。

删除 静态 ,就可以了。

注意 makefile 中可能还有其他错误。