未能执行;制造;在ubuntugcc中

未能执行;制造;在ubuntugcc中,c,linux,ubuntu,gcc,makefile,C,Linux,Ubuntu,Gcc,Makefile,我有几个文件,我正试图在Ubuntu中使用gcc编译。我有vmware机器16.04 ubuntu,这是一台64位计算机。我在makefile中添加了32位编译的标志。(-m32标志) 这是生成文件: 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 bins

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

这是生成文件:

    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 
我编译代码的尝试没有成功,因为我收到了以下错误:

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
**我试过-**

  • 将-c标志添加到make文件中的ph.c文件。然而,它没有多大意义,因为它有一个主要功能。没有成功。
  • 在makefile中添加sum-m32标志,以及已经写入的内容。没有成功
  • 文件“ph.c”是以下文件-

    #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
    
    }
    
    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
    
    \ifndef\u BIN\u SEM\H
    #定义\u BIN\u SEM\u H
    #包括“binsem.h”
    #包括
    #包括“atomic.h”
    typedef无符号长扫描;
    void binsem_init(sem_t*s,int init_val){
    if(init_val==1){
    *s=1;
    }
    否则{
    *s=0;
    }
    }
    空腔箱密封(扫描电镜){
    xchg(s,1);/*发送s的指针和新值1*/
    }
    int binsem\U down(扫描电镜){
    int标志=0;
    while(标志==0){
    xchg(s,0);/*尝试向下更改值*/
    如果(*s!=0){/*更改失败*/
    如果(raise(SIGALRM)!=0{/*raise成功返回0*/
    返回-1;
    }
    }否则{
    flag=1;
    返回0;
    }
    }
    }
    #恩迪夫
    

    有什么想法吗?

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

    删除
    静态
    修饰符,该修饰符将正常工作


    但是,在
    Makefile
    中还有许多其他问题很可能会导致问题:

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

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


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

    错误消息非常清楚:

    在博士课程中,您(可能习惯于Java?)有:

    在C中:

  • static()表示内部链接(仅在当前翻译单元中有效(在本例中为ph.o)),因此链接器(加载程序)不会“看到”静态符号

  • 链接到应用程序(不是动态库或共享对象(.so:linked with-shared)的代码必须显式定义main,并且链接器应该可以看到它

  • 以上两个因素的结合,会导致你所经历的一切

    移除静态,您就会没事了


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

    您好,谢谢!你能解释一下为什么会出问题吗?我可以在不删除“静态”的情况下解决问题吗?@Alan为什么需要
    main
    功能的内部链接?使用
    static
    要解决的问题是什么?不,你不应该使用任何修饰符或限定符。@Someprogrammerdude实际上我不确定。我应该写两个库来使用这个主函数(ut.c,binsem.c)。然后你可以将main移到binsem.c(并修复这个操作将触发的错误,因为我可以看到它引用了一些全局变量),并且仍然删除static。请你的代码将其减少到问题的一部分。您当前的代码包含了许多与您的问题无关的内容-最小样本通常看起来类似于良好的单元测试:仅执行一项任务,输入值指定为再现性。您好,我相信我的问题符合标准。我不能再最小化它了,这是运行代码所需的绝对最小代码。这远远不是重现错误所需的最小代码。除了
    main()
    (和
    main()
    可以有一个空的正文)之外,您不需要任何变量或任何函数。说真的,这可以用一行源文件来复制:
    static int main(void){}
    #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
    
    (.text+0x18): undefined reference to `main'
    
    static int main(int argc, char *argv[])