Как связать мой код C с библиотекой PCRE? (Ошибки компоновщика в настоящее время выбрасываются.) - PullRequest
6 голосов
/ 28 июня 2011

Проблема

Примечание: У меня изначально была эта проблема в гораздо более крупном проекте;поэтому я сократил код до тестового примера, который вы видите ниже.

Я не могу понять, как получить следующий тестовый код для компиляции.В частности, это выглядит так, как будто компоновщик не может найти библиотеку 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]

Ответ найден!

Все флаги внешних библиотек должны быть перечислены после всехобъектные файлы. Таким образом, Makefile должен был выглядеть так:

GCC_LINK = $(GCC_CMD) -L/usr/local/lib $(GCC_OPTIONS)

GCC_LINK_ALL = $(GCC_LINK) main.o -lpcre

Спасибо всем, кто ответил с ответами.: -)

1 Ответ

1 голос
/ 28 июня 2011

Возможно ли, что компоновщик находит предварительно собранную версию libpcre.so?

Попробуйте совет из этого вопроса : "указать / usr / local / lib / libpcre.a в командной строке компилятора ... избегайте включения -lpcre ".

...