g++ 링킹 중 C++ 라이브러리가 C 표준 라이브러리를 참조하지 못합니다.

scan15g의 이미지

안녕하세요.

오픈리스크 임베디드 환경에 간단한 C++코드를 얹어 테스트를 해 보려고 하는 학생 입니다.
오픈리스크 크로스 컴파일러를 설치 하고 링커를 사용해서 간단한 C++코드를 바이너리로 만들어 보려고 하는데요.

지금 문제는 크로스 컴파일러의 링킹 과정에서 C++ 라이브러리가 C 표준 라이브러리를 참조하지 못하는 것 같습니다.
예를 들면,
C++ 의 operator new 를 구현하기 위해 C의 malloc 이 사용 되는데,
C++ 라이브러리가 malloc 에 대한 undefined reference 에러를 내는 것 입니다.

제가 한 일을 일단 설명 드리면,
링킹 과정에서 필요하다고하는 라이브러리를 찾아서 모두 링크를 하는데 성공했습니다.
링킹을 수행하는 명령어는 다음과 같습니다.

or32-elf-ld init.o test.o -o eprom.elf C++ -T or32.ld -Map eprom.map -L /opt/openrisc/or32-elf/lib/ -L /opt/openrisc/lib/gcc/or32-elf/4.5.1-or32-1.0rc4/ -lgcc -lc -lstdc++

1. or32.ld 라는 링커 스크립트로 init.o와 test.o 파일에있는 모든 섹션을 메모리에 할당하는데에 성공 했습니다.
2. 라이브러리 폴더를 -L 로 지정하여 필요한 라이브러리를 -lgcc -lc -lstdc++ 로 링킹 하였습니다. (-lstdc++을 링킹 하지 않았을 때는 operator new 에 대한 undefined reference 에러가 발생했었습니다.)

그런데 문제는 2번 과정까지 온 뒤에 operator new 라이브러리 내에서 에러가 발생 합니다.
실제로는 많은 양의 undefined reference 에러가 나타납니다. 아래는 그중의 일부 입니다.

or32-elf-ld init.o test.o -o eprom.elf -T or32.ld -Map eprom.map -L /opt/openrisc/or32-elf/lib/ -L /opt/openrisc/lib/gcc/or32-elf/4.5.1-or32-1.0rc4/ -lgcc -lc -lstdc++ 
 
/opt/openrisc/or32-elf/lib//libstdc++.a(new_op.o): In function `operator new(unsigned long)':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/new_op.cc:52: undefined reference to `malloc'
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/new_op.cc:63: undefined reference to `malloc'
/opt/openrisc/or32-elf/lib//libstdc++.a(eh_alloc.o): In function `__cxa_allocate_exception':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:102: undefined reference to `malloc'
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:135: undefined reference to `memset'
/opt/openrisc/or32-elf/lib//libstdc++.a(eh_alloc.o): In function `__cxa_free_exception':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:156: undefined reference to `free'
/opt/openrisc/or32-elf/lib//libstdc++.a(eh_alloc.o): In function `__cxa_allocate_dependent_exception':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:166: undefined reference to `malloc'
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:197: undefined reference to `memset'
/opt/openrisc/or32-elf/lib//libstdc++.a(eh_alloc.o): In function `__cxa_free_dependent_exception':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:219: undefined reference to `free'
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/eh_alloc.cc:213: undefined reference to `__udivsi3'
/opt/openrisc/or32-elf/lib//libstdc++.a(del_op.o): In function `operator delete(void*)':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/del_op.cc:44: undefined reference to `free'
/opt/openrisc/or32-elf/lib//libstdc++.a(si_class_type_info.o): In function `std::type_info::operator==(std::type_info const&) const':
/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/typeinfo:123: undefined reference to `strcmp'

그래서 에러 메세지에서 에러가 났다고 말하는 함수가 포함된 파일의 내용을 확인 했습니다.
내용은 다음처럼 나옵니다.

파일 경로

/opt/gnu-stable/bd-elf/or32-elf/libstdc++-v3/libsupc++/../../../../unisrc/libstdc++-v3/libsupc++/new_op.cc

파일 내용

// Support routines for the -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2009
// Free Software Foundation
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
 
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.
 
#include <bits/c++config.h>
#include <cstdlib>
#include <exception_defines.h>
#include "new"
 
using std::new_handler;
using std::bad_alloc;
#if _GLIBCXX_HOSTED
using std::malloc;
#else
// A freestanding C runtime may not provide "malloc" -- but there is no
// other reasonable way to implement "operator new".
extern "C" void *malloc (std::size_t);
#endif
 
extern new_handler __new_handler;
 
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) throw (std::bad_alloc)
{
  void *p;
 
  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
#ifdef __EXCEPTIONS
        throw bad_alloc();
#else
        std::abort();
#endif
      handler ();
      p = (void *) malloc (sz);
    }
 
  return p;
}

한눈에 보기에 C++의 기본적인 operator인 new를 정의하는 함수 같습니다.
그리고 new를 구현 하기 위해 malloc을 사용하고 있구요...
그런데 여기서 malloc 를 찾을 수 없다고 나오는 겁니다...
더이상 제가 할 수 있는 일이 없어보였습니다.

제 짧은 지식으로 정리해 보자면 libstdc++.a 라이브러리에 있는 오브젝트들이 참조하는 cc 파일, 즉 c++ 라이브러리파일 내에서 사용하는 c 의 라이브러리가 모조리 찾을 수 없는 에러가 나타나는데요...
표준 라이브러리에서 이런 일이 생기니까 어떻게 대응해야 할 지 모르겠습니다.

몇 가지 가능성을 생각해 보면,
1. 오픈리스크 크로스 컴파일러 설치가 잘못 되었다.
2. C++라이브러리가 C의 라이브러리를 참조할 수 있도록 하는 옵션이 있는데 모른다.
로 생각하고 있지만...

도무지 알 수가 없습니다 ㅠㅜ
포기해야 하는 걸까요...ㅠㅜ

고수 여러분의 지나가는 작은 한마디라도 해당 검색어로 구글링 해서 찾을 수 있을 테니,
꼭 도움 부탁 드립니다!

감사합니다!

익명 사용자의 이미지

정적 라이브러리 링크 시에 불필요한 심볼들은 제거됩니다.
libc 와 libstdc++ 의 링크 순서를 바뀌거나,
ld 의 --start-group, --end-group 옵션을 사용해서 필요한 라이브러리들을 그룹으로 묶어주세요.

익명 사용자의 이미지

익명 사용자의 이미지

특별한 이유가 없으면
C, C++라이브러리를 알고 있는 g++로 링크하세요.
ld는 심지어 libc도 지정해 줘야 합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.