问题
Note:我最初在一个更大的项目中遇到了这个问题;所以我将代码缩减为您在下面看到的测试用例。
我不知道如何编译以下测试代码。具体来说,链接器似乎无法找到 PCRE 库(有关 PCRE 的配置方式,请参阅下文)。尽管有明确的-L/usr/local/lib -lpcre
被传递给链接器(PCRE 安装在/usr/local
目录结构)。
我究竟做错了什么? :-(
控制台输出为:
$ make
rm -f ./*.o
gcc -ansi -Wall -pedantic-errors -I/usr/local/include -g0 -O3 -static -static-libgcc -march=i686 -malign-double -m128bit-long-double -c main.c -o main.o
gcc -ansi -Wall -pedantic-errors -L/usr/local/lib -lpcre -g0 -O3 -static -static-libgcc -march=i686 -malign-double -m128bit-long-double main.o -o pcre_test_1_i686
main.o:main.c:(.text+0x100): undefined reference to `pcre_compile2'
main.o:main.c:(.text+0x12e): undefined reference to `pcre_study'
main.o:main.c:(.text+0x16e): undefined reference to `pcre_exec'
main.o:main.c:(.text+0x19f): undefined reference to `pcre_copy_substring'
collect2: ld returned 1 exit status
make: *** [all] Error 1
相关文件
PCRE配置和编译环境
./configure --disable-shared --enable-static --disable-cpp --enable-rebuild-chartables --enable-utf8 --enable-unicode-properties --enable-newline-is-any --disable-stack-for-recursion --with-posix-malloc-threshold=2 --with-link-size=4
CC="gcc"
CFLAGS="-g0 -O3 -static -static-libgcc -march=i686 -malign-double -m128bit-long-double"
LD_RUN_PATH="/usr/local/include:/usr/local/lib"
main.c
#define PCRE_STATIC
#include <pcre.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define OUTPUT_SIZE 12
#define SUBSTRING_SIZE 16
int main(int argc, char *argv[]) {
pcre *re;
pcre_extra *extra;
const char *input = "get food";
const char *pattern = "^\\s*get\\s+(\\w+)\\s*$\0";
int options = PCRE_CASELESS | PCRE_UTF8 | PCRE_UCP;
int error_code = 0;
int error_offset = 0;
const char *compile_error;
const char *study_error;
int output[OUTPUT_SIZE];
char substring[SUBSTRING_SIZE];
int matched = 0;
int is_error = 0;
int index = 0;
for(index = 0; index < OUTPUT_SIZE; index++) {
output[index] = 0;
}
re = pcre_compile2( pattern,
options,
&error_code,
&compile_error,
&error_offset,
NULL );
if(re == NULL) {
fprintf(stderr, "PCRE regular expression error at position %d: %s", error_offset, compile_error);
exit(EXIT_FAILURE);
}
if(error_code == 0) {
extra = pcre_study( re,
0,
&study_error );
}
else {
fprintf(stderr, "PCRE regular expression error at position %d: %s", error_offset, compile_error);
extra = NULL;
}
matched = pcre_exec( re,
extra,
input,
(int)strlen(input),
0, /* Start at the beginning of the string */
0,
output,
OUTPUT_SIZE );
if(matched > 1) {
int status = pcre_copy_substring( input,
output,
matched,
1,
substring,
SUBSTRING_SIZE );
if(status < 0) {
switch(status) {
case PCRE_ERROR_NOMEMORY:
fprintf(stderr, "PCRE substring extraction error: %s", "Buffer too small");
break;
case PCRE_ERROR_NOSUBSTRING:
fprintf(stderr, "PCRE substring extraction error: %s", "Invalid substring number");
break;
}
is_error = 1;
}
}
printf("Capture group 1 is: '%s'\n", substring);
if(is_error) {
printf("There was an error with the pcre_copy_substring() function.\n");
}
return EXIT_SUCCESS;
}
Makefile
PACKAGE = pcre_test
VERSION = 1
# -ansi == ANSI C
# -std=iso9899:199409 == ANSI C w/ Amendment 1
# -std=c99 == ISO C99
GCC_CMD = gcc -ansi -Wall -pedantic-errors
# Generic: i686
# Intel: core2, corei7, corei7-avx
# AMD: k8-sse3, opteron-sse3, athlon64-sse3, amdfam10
ARCH = i686
RELEASE_FILE = $(PACKAGE)_$(VERSION)_$(ARCH)
GCC_OPTIONS = -g0 -O3 -static -static-libgcc -march=$(ARCH) -malign-double -m128bit-long-double
GCC_COMPILE = $(GCC_CMD) -I/usr/local/include $(GCC_OPTIONS)
GCC_LINK = $(GCC_CMD) -L/usr/local/lib -lpcre $(GCC_OPTIONS)
GCC_LINK_ALL = $(GCC_LINK) main.o
all: clean build_main
$(GCC_LINK_ALL) -o $(RELEASE_FILE)
build_main:
$(GCC_COMPILE) -c main.c -o main.o
clean:
rm -f ./*.o
[EDIT]
答案已找到!
必须列出所有外部库标志after所有目标文件。就这样Makefile应该是这样的:
GCC_LINK = $(GCC_CMD) -L/usr/local/lib $(GCC_OPTIONS)
GCC_LINK_ALL = $(GCC_LINK) main.o -lpcre
感谢所有回复的人。 :-)