g++ 링킹 중 C++ 라이브러리가 C 표준 라이브러리를 참조하지 못합니다.
안녕하세요.
오픈리스크 임베디드 환경에 간단한 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 옵션을 사용해서 필요한 라이브러리들을 그룹으로 묶어주세요.
영어를 못하시나요?
http://sourceware.org/binutils/docs-2.23.1/ld/Options.html#Options
특별한 이유가 없으면 C, C++라이브러리를 알고
특별한 이유가 없으면
C, C++라이브러리를 알고 있는 g++로 링크하세요.
ld는 심지어 libc도 지정해 줘야 합니다.
댓글 달기