gpt4 book ai didi

c - Ubuntu gcc 中无法执行 "make"

转载 作者:行者123 更新时间:2023-11-30 19:59:47 26 4
gpt4 key购买 nike

我有几个文件正在尝试在 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

**我尝试过 - **

  1. 将 -c 标志添加到 make 文件中的 ph.c 文件中。然而它没有多大意义,因为它有一个主要功能。没有成功。
  2. 除了已经编写的内容之外,还在 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

}

makefile 还尝试编译这些文件 - ut.cbinsem.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

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

有什么想法吗?

最佳答案

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

删除 static 修饰符就可以了。

<小时/>

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

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

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

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

关于c - Ubuntu gcc 中无法执行 "make",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53391352/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com