当我用make编译我的C程序时,我得到了一个错误。我已经开发这个项目几天了,在我需要添加一个外部文件(semaphore_v2.h)之前,一切都编译得很好。我不知道是不是导入错误,但当我试图用它编译项目时,它没有编译。下面的一些信息。
PD:如果重新定义的警告“__USE_XOPEN”是我不知道如何修复它的原因。另一个错误是对“fmin”的未定义引用,可以忽略,我知道如何解决它。
我已经检查了.h文件的警卫。我还检查过我没有多次插入,也没有包括.c文件。我猜这个错误一定是因为我不知道如何解决的警告,或者我在更新makefile时出错了,但我没有看到它。
出错
(我已经包含了发生错误的详细模式):
> gcc -c bowman.c -gdb -Wall -Wextra
> gcc -c utils.c -gdb -Wall -Wextra
> gcc bowman.o utils.o -o bowman -ggdb -Wall -Wextra
> gcc -c poole.c -ggdb -Wall -Wextra -lpthread
> In file included from request_queue.h:7,
> from poole.c:8:
> semaphore_v2.h:19: warning: "__USE_XOPEN" redefined
> 19 | #define __USE_XOPEN
>
> In file included from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
> from /usr/include/stdio.h:27,
> from poole.c:3:
> /usr/include/features.h:355: note: this is the location of the previous definition
> 355 | # define __USE_XOPEN 1
>
> poole.c: In function âworkerâ:
> poole.c:26:20: warning: unused parameter âargsâ [-Wunused-parameter]
> 26 | void *worker(void *args){
> | ~~~~~~^~~~
> poole.c: In function âprocess_new_bowmanâ:
> poole.c:159:30: warning: unused parameter âdataâ [-Wunused-parameter]
> 159 | int process_new_bowman(char *data, int fd){
> | ~~~~~~^~~~
> gcc -c request_queue.c -ggdb -Wall -Wextra -lpthread
> gcc -v poole.o utils.o request_queue.o -o poole -ggdb -Wall -Wextra -lpthread
> Using built-in specs.
> COLLECT_GCC=gcc
> COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
> OFFLOAD_TARGET_DEFAULT=1
> Target: x86_64-linux-gnu
> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
> Thread model: posix
> Supported LTO compression algorithms: zlib zstd
> gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)
> COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/
> LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../:/lib/:/usr/lib/
> COLLECT_GCC_OPTIONS='-v' '-o' 'poole' '-ggdb' '-Wall' '-Wextra' '-mtune=generic' '-march=x86-64' '-dumpdir' 'poole.'
> /usr/lib/gcc/x86_64-linux-gnu/11/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper -plugin-opt=-fresolution=/tmp/ccYawT3g.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o poole /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11/../../.. poole.o utils.o request_queue.o -lpthread -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/11/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crtn.o
> /usr/bin/ld: request_queue.o: in function `SEM_constructor_with_name':
> /home/guille/git-repos/HAL9000System/semaphore_v2.h:78: multiple definition of `SEM_constructor_with_name'; poole.o:/home/guille/git-repos/HAL9000System/semaphore_v2.h:78: first defined here
> /usr/bin/ld: request_queue.o: in function `SEM_constructor':
> /home/guille/git-repos/HAL9000System/semaphore_v2.h:100: multiple definition of `SEM_constructor'; poole.o:/home/guille/git-repos/HAL9000System/semaphore_v2.h:100: first defined here
> /usr/bin/ld: request_queue.o: in function `SEM_init':
> /home/guille/git-repos/HAL9000System/semaphore_v2.h:115: multiple definition of `SEM_init'; poole.o:/home/guille/git-repos/HAL9000System/semaphore_v2.h:115: first defined here
> /usr/bin/ld: request_queue.o: in function `SEM_destructor':
> /home/guille/git-repos/HAL9000System/semaphore_v2.h:127: multiple definition of `SEM_destructor'; poole.o:/home/guille/git-repos/HAL9000System/semaphore_v2.h:127: first defined here
> /usr/bin/ld: request_queue.o: in function `SEM_wait':
> /home/guille/git-repos/HAL9000System/semaphore_v2.h:141: multiple definition of `SEM_wait'; poole.o:/home/guille/git-repos/HAL9000System/semaphore_v2.h:141: first defined here
> /usr/bin/ld: request_queue.o: in function `SEM_signal':
> /home/guille/git-repos/HAL9000System/semaphore_v2.h:159: multiple definition of `SEM_signal'; poole.o:/home/guille/git-repos/HAL9000System/semaphore_v2.h:159: first defined here
> /usr/bin/ld: poole.o: in function `worker':
> /home/guille/git-repos/HAL9000System/poole.c:43: undefined reference to `fmin'
> collect2: error: ld returned 1 exit status
> make: *** [makefile:16: poole] Error 1
这个
制作文件
如下所示:
> all: bowman Poole discovery
>
> bowman: bowman.o utils.o
> gcc bowman.o utils.o -o bowman -ggdb -Wall -Wextra
>
> bowman.o: bowman.c utils.h
> gcc -c bowman.c -ggdb -Wall -Wextra
>
> discovery: discovery.o utils.o
> gcc discovery.o utils.o -o discovery -ggdb -Wall -Wextra
>
> discovery.o: discovery.c utils.h
> gcc -c discovery.c -ggdb -Wall -Wextra
>
> poole: poole.o utils.o request_queue.o
> gcc -v poole.o utils.o request_queue.o -o poole -ggdb -Wall -Wextra -lpthread
>
> poole.o: poole.c utils.h request_queue.h
> gcc -c poole.c -ggdb -Wall -Wextra -lpthread
>
> request_queue.o: request_queue.c request_queue.h
> gcc -c request_queue.c -ggdb -Wall -Wextra -lpthread
>
> utils.o: utils.c utils.h
> gcc -c utils.c -ggdb -Wall -Wextra
>
> .PHONY: clean
> clean:
> rm *.o
> rm bowman
> rm poole
> rm discovery
以下是项目中每个文件中包含的标题:
utils.h
:
#ifndef _UTILS_H
#define _UTILS_H
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
...
#endif
Poole.c
:
#define _GNU_SOURCE
#include <stdio.h>
#include <math.h>
#include <sys/poll.h>
#include "utils.h"
#include "request_queue.h"
...
utils.c
:
#include "utils.h"
...
request_queue.h
:
#ifndef _REQUEST_QUEUE
#define _REQUEST_QUEUE
#include <pthread.h>
#include <stdbool.h>
#include "semaphore_v2.h"
...
#endif
request_queue.c
:
#include "request_queue.h"
...
semaphore_v2.h
:
#ifndef _MOD_SEMAPHORE_H_
#define _MOD_SEMAPHORE_H_
/////////////////////////////////////////////////////////////////////////////
/**
* @file semaphore.h
* @author Jorge Solanas
* @date October 5, 2011
* @brief Library to facilitate the use of semaphores
*
* (c) Copyright La Salle BCN, 2011.
* All rights reserved. Copying or other reproduction of this program except
* for archival purposes is prohibited without written consent of
* La Salle BCN.
*/
//////////////////////////////////////////////////////////////////////////////
//#define __USE_SVID
#define __USE_XOPEN
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <assert.h>
#include <stdlib.h>
/**
* Union which must be explicitly declared by the application.
* It is the fourth argument of the semctl function, and it is
* optional, depending upon the operation requested.
*/
/*union semun
{
int val;
struct semid_ds * buf;
unsigned short * array;
};*/
/**
* Struct used to indicate to a semaphore which operation is
* going to be applied (number of the semaphore, operation and
* flags).
*/
typedef struct
{
unsigned short int sem_num;
short int sem_op;
short int sem_flg;
} sembuf;
/**
* Struct with all the info about a semaphore. In this case,
* only the id is specified.
*/
typedef struct
{
int shmid;
} semaphore;
/**
* This file provides a simple but useful abstraction for
* controlling acces by multiple processes to a common resource.
*/
//////////////////////////////////////////////////////////////////////////////
// V2 SEMAPHORE //
/////////////////////////////////////////////////////////////////////////////
/**
* Method which creates a semaphore which a specific identifier/name.
* Very useful for the session S8 ;)
* @param sem The var where semaphore will be created
* @param name Semaphore name. If there isn't semaphore with this name, it is created.
If it exists, you get the memory region
* @return int The result of the operation executed
*/
int SEM_constructor_with_name(semaphore * sem, key_t key) {
// IPC_CREAT: if this is specified, and a semaphore with the given key does not exist, it is created, otherwise the call returns with -1, setting the appropriate errno value.
sem->shmid = semget(key, 1, IPC_CREAT | 0644);
if (sem->shmid < 0) return sem->shmid;
return 0;
}
//////////////////////////////////////////////////////////////////////////////
// V1 SEMAPHORE //
/////////////////////////////////////////////////////////////////////////////
/**
* Method which creates a semaphore
* @param sem The var where semaphore will be created
* @return int The result of the operation executed
*/
int SEM_constructor (semaphore * sem)
{
assert (sem != NULL);
sem->shmid = semget (IPC_PRIVATE, 1, IPC_CREAT | 0600);
if (sem->shmid < 0) return sem->shmid;
return 0;
}
/**
* Method which initializes a semaphore
* @param sem The semaphore to initialize
* @param v The value to which the semaphores will be
* initialized
* @return int The result of the operation executed
*/
int SEM_init (const semaphore * sem, const int v)
{
unsigned short _v[1] = {v};
assert (sem != NULL);
return semctl (sem->shmid, 0, SETALL, _v);
}
/**
* Method to destroy a semaphore
* @param sem The semaphore to destroy
* @return int The result of the operation executed
*/
int SEM_destructor (const semaphore * sem)
{
assert (sem != NULL);
return semctl (sem->shmid, 0, IPC_RMID, NULL);
}
/**
* Method to apply a wait operation, in order to warn that a
* process is going to use a common resource. The semaphore
* counter will be decreased. If counter has the value zero, the
* process will be added to the semaphore's queue
* @param sem The semaphore where wait operation will be applied
* @return int The result of the operation executed
*/
int SEM_wait (const semaphore * sem)
{
struct sembuf o = {0, -1, SEM_UNDO};
assert (sem != NULL);
return semop(sem->shmid, &o, 1);
}
/**
* Method to apply a signal operation, in order to warn that a
* process has released a common resource. The semaphore counter
* will be increased. If counter had the value zero and there
* are processes in the queue, the top one has the access to the
* common resource granted.
* @param sem The semaphore where signal operation will be
* applied
* @return int The result of the operation executed
*/
int SEM_signal (const semaphore * sem)
{
struct sembuf o = {0, 1, SEM_UNDO};
assert (sem != NULL);
return semop(sem->shmid, &o, 1);
}
#endif /* _MOD_SEMAPHORE_H_ */