2014-05-23 9 views
2

이 오류가 계속 발생하며 이유를 알지 못합니다. 나는이 일을하려고 노력하면서 내 마음을 잃어 가고있다. 어떤 도움이라도 대단히 감사 할 것이다.원자 로깅 작업을 시도하는 중

clang: error: linker command failed with exit code 1

코드 : 나는 도움의 컴파일이 필요

1 #include <stdio.h> 
2 #include <stdlib.h> 
3 #include <string.h> 
4 #include <unistd.h> 
5 #include "atomic_logger.h" 
6 
7 #define BUFSIZE 1024 
8 
9 int main (int argc, char *argv[]) { 
10 char buf[BUFSIZE]; 
11 pid_t childpid = 0; 
12 int i, n; 
13 
14 if (argc != 3){  /* check for valid number of command-line arguments */ 
15  fprintf (stderr, "Usage: %s processes filename\n", argv[0]); 
16  return 1; 
17 } 
18 n = atoi(argv[1]);        /* create a process chain */ 
19 for (i = 1; i < n; i++) 
20  if ((childpid = fork())) 
21   break; 
22 if (childpid == -1) { 
23  perror("Failed to fork"); 
24  return 1; 
25 } 
26 
27 if (atomic_log_open(argv[2]) == -1) {    /* open atomic log file */ 
28  fprintf(stderr, "Failed to open log file"); 
29  return 1; 
30 } 
31         /* log the output, using two different forms */ 
32 atomic_log_printf("i:%d process:%ld", i, (long)getpid()); 
33 
34 atomic_log_printf(" parent:%ld child:%ld\n", (long)getppid(), (long)childpid); 
35 
36 
37 if (atomic_log_send() == -1) { 
38  fprintf(stderr, "Failed to send to log file"); 
39  return 1; 
40 } 
41 atomic_log_close(); 
42 return 0; 
43 } 

네, 학교 과제의 일부입니다,하지만 난 도움 코딩이 필요하지 않습니다. 왜 컴파일되지 않을까요? 이 파일과 같은 폴더에 atomic_logger.c와 atomic_logger.h를 넣었습니다.하지만이 오류는 여전히 발생합니다. 무슨 일 이니? 나는 때문에 누락 분명 뭔가가

1 #include <errno.h> 
    2 #include <fcntl.h> 
    3 #include <stdarg.h> 
    4 #include <stdio.h> 
    5 #include <stdlib.h> 
    6 #include <string.h> 
    7 #include <unistd.h> 
    8 #include <sys/stat.h> 
    9 
10 #define FILE_PERMS (S_IRUSR | S_IWUSR| S_IRGRP | S_IROTH) 
11 #define OPEN_FLAGS (O_WRONLY|O_APPEND|O_CREAT) 
12 typedef struct list { 
13 char *entry; 
14 int len; 
15 struct list *next; 
16 } list; 
17 
18 static int fd = -1; 
19 static list *first = NULL; 
20 static list *last = NULL; 
21 
22 
23 /* ----------------------------------------------------------------- 
24 Private Functions 
25 */ 
26 
27 /* This is the same as write, but restarts if interrupted by a signal */ 
28 static ssize_t my_write(int fd, void *buf, size_t size) { 
29 ssize_t bytes; 
30 
31 while (((bytes = write(fd, buf, size)) == -1) && (errno == EINTR)); 
32 return bytes; 
33 } 
34 
35 /* Insert an entry with the given len field, but allocate extra bytes.*/ 
36 /* Return a pointer to the new entry on success or NULL on failure. */ 
37 static list *insert_new_entry(int len, int extra) { 
38 char *new_str; 
39 list *new_entry; 
40 
41 new_entry = (list *)malloc(sizeof(list)+len+extra); 
42 if (new_entry == NULL) 
43  return NULL; 
44 new_str = (char *)new_entry+sizeof(list); 
45 new_entry->entry = new_str; 
46 new_entry->next = NULL; 
47 new_entry->len = len; 
48 if (last == NULL) 
49  first = new_entry; 
50 else 
51  last->next = new_entry; 
52 last = new_entry; 
53 return new_entry; 
54 } 
55 
56 /* Return the sum of the lengths of all the entries.     */ 
57 static int get_length() { 
58 int len = 0; 
59 list *current; 
60 
61 current = first; 
62 while (current != NULL) { 
63  len += current->len; 
64  current = current->next; 
65 } 
66 return len; 
67 } 
68 
69 /* Clear the list and free all the space.        */ 
70 static void clear() { 
71 list *current; 
72 list *free_entry; 
73 
74 current = first; 
75 while (current != NULL) { 
76  free_entry = current; 
77  current = current->next; 
78  free(free_entry); 
79 } 
80 first = NULL; 
81 last = NULL; 
82 } 
83 
84 /* ----------------------------------------------------------------- 
85 Public Functions 
86 */ 
87 
88 /* Open the given file for logging.         */ 
89 /* If successful, return 0. Otherwise, return -1 with errno set.  */ 
90 int atomic_log_open(char *fn) { 
91 while (fd = open(fn, OPEN_FLAGS, FILE_PERMS), fd == -1 && errno == EINTR); 
92 if (fd < 0) 
93  return -1; 
94 return 0; 
95 } 
96 
97 /* Insert the given array with given size in the list.    */ 
98 /* If successful, return 0. Otherwise, return -1 with errno set.  */ 
99 int atomic_log_array(char *s, int len) { 
100 list *new_entry; 
100 list *new_entry; 
101 
102 if (fd < 0) { 
103  errno = EINVAL; 
104  return -1; 
105 } 
106 new_entry = insert_new_entry(len, 0); 
107 if (new_entry == NULL) 
108  return -1; 
109 (void)memcpy(new_entry->entry, s, len); 
110 return 0; 
111 } 
112 
113 /* Insert the given string in the list.        */ 
114 /* Do not include the string terminator.        */ 
115 /* If successful, return 0. Otherwise, return -1 with errno set.  */ 
116 int atomic_log_string(char *s) { 
117 return atomic_log_array(s, strlen(s)); 
118 } 
119 
120 /* Insert an entry in the list.          */ 
121 /* The syntax is similar to printf.         */ 
122 /* Include the string terminator but do not count it in the length. */ 
123 /* If successful, return 0. Otherwise, return -1 with errno set.  */ 
124 int atomic_log_printf(char *fmt, ...) { 
125 va_list ap; 
126 char ch; 
127 int len; 
128 list *new_entry; 
129 
130 if (fd < 0) { 
131  errno = EINVAL; 
132  return -1; 
133 } 
134 va_start(ap, fmt); 
135 len = vsnprintf(&ch, 1, fmt, ap); 
136 new_entry = insert_new_entry(len, 1); 
137 if (new_entry == NULL) 
138  return -1; 
139 vsprintf(new_entry->entry, fmt, ap); 
140 return 0; 
141 } 
142 
143 /* Attempt to log the entire list with a single write.    */ 
144 /* Clear the list if successful.          */ 
145 /* If successful, return 0. Otherwise, return -1 with errno set.  */ 
146 /* If the entire list cannot be logged with a single write, this is */ 
147 /* considered a failure.           */ 
148 int atomic_log_send() { 
149 char *buf; 
150 list *current; 
151 int len; 
152 
153 if (fd < 0) { 
154  errno = EINVAL; 
155  return -1; 
156 } 
157 len = get_length(); 
158 if (len == 0) 
159  return 0; 
160 buf = (char *)malloc(len); 
161 if (buf == NULL) 
162  return -1; 
163 current = first; 
164 len = 0; 
165 while (current != NULL) { 
166  (void)memcpy(buf+len, current->entry, current->len); 
167  len += current->len; 
168  current = current->next; 
169 } 
170 if (my_write(fd, buf, len) != len) { 
171  free(buf); 
172  errno = EAGAIN; 
173  return -1; 
174 } 
175 free(buf); 
176 clear(); 
177 return 0; 
178 } 
179 
180 /* Clear the list and free all the space without logging anything. */ 
181 int atomic_log_clear() { 
182 clear(); 
183 return 0; 
184 } 
185 
186 /* Close the log file. Any data not yet logged is lost.    */ 
187 int atomic_log_close() { 
188 int retval; 
189 clear(); 
190 while (retval = close(fd), retval == -1 && errno == EINTR) ; 
191 return retval; 
192 } 

상황이 나에게 제대로 선언 봐,하지만 난 확신 :

1 int atomic_log_array(char *s, int len); 
    2 int atomic_log_clear(); 
    3 int atomic_log_close(); 
    4 int atomic_log_open(char *fn); 
    5 int atomic_log_printf(char *fmt, ...); 
    6 int atomic_log_send(); 
    7 int atomic_log_string(char *s); 

및 atomic_logger.c은 다음과 같다 : 다음과 같이 atomic_logger.h입니다 내가 오류 메시지는 다음과 같습니다 제가이 문제를 해결할 수 있도록 사전에

imacbook:lab4 smythe1$ gcc -o ex8/chainforkopenlog ex8/chainforkopenlog.c 
Undefined symbols for architecture x86_64: 
    "_atomic_log_close", referenced from: 
     _main in chainforkopenlog-44aa15.o 
    "_atomic_log_open", referenced from: 
     _main in chainforkopenlog-44aa15.o 
    "_atomic_log_printf", referenced from: 
     _main in chainforkopenlog-44aa15.o 
    "_atomic_log_send", referenced from: 
     _main in chainforkopenlog-44aa15.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

감사합니다 ... 당신이있어

답변

2

gccatomic_logger.c을 컴파일하거나 연결해서는 안됩니다. 모두 하나의 호출에 -

가장 간단한 해결책이 최종 출력 바이너리 함께 나열된 .c 모든 파일 및 링크을 컴파일 gcc에 알려줍니다

$ gcc -o ex8/chainforkopenlog ex8/chainforkopenlog.c ex8/atomic_logger.c 

될 것이다.

대안은이 스위치를 사용 -c.o 대응하는 파일 만 각 파일 .c컴파일 독립적이다. 그런 다음 링크 모두 출력 바이너리 용 .o 파일이 함께 있습니다. 그것은 자동적으로 atomic_logger.c보고 GCC를 통보하지 않습니다 - #include "atomic_logger.h" 최종 연결 과정을 함께 할 아무것도하지 않는

$ gcc -c ex8/chainforkopenlog.c  # Produces chainforkopenlog.o 
$ gcc -c ex8/atomic_logger.c   # Produces atomic_logger.o 

$ gcc -o ex8/chainforkopenlog chainforkopenlog.o atomic_logger.o 

참고. 헤더 파일의 내용을 포함 된 위치에 복사하고 붙여 넣기 만합니다.

+1

조나단에게 고맙습니다.이 문제가 해결되었습니다. 나는 그것이 명백한 무엇인가 명백했다라는 것을 알고 있었다. –

관련 문제