2011-09-23 76 views
37

Tôi cố gắng biên dịch mã cpp này trên con sư tử osx nhưng tôi gặp lỗi.Lỗi khi biên dịch một số mã C++ đơn giản

#include <iostream> 

using namespace std; 

int main (int argc, char *argv[]) 
{ 
    for(int i = 0; i < 10; i++) 
    { 
     cout << "hi"; 
     cout << endl; 
    } 

    return 0; 
} 

Để biên dịch:

cc main.cpp 

Lỗi:

Undefined symbols for architecture x86_64: 
    "std::cout", referenced from: 
     _main in ccBdbc76.o 
    "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from: 
     _main in ccBdbc76.o 
    "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from: 
     _main in ccBdbc76.o 
    "std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))", referenced from: 
     _main in ccBdbc76.o 
    "std::ios_base::Init::Init()", referenced from: 
     __static_initialization_and_destruction_0(int, int)in ccBdbc76.o 
    "std::ios_base::Init::~Init()", referenced from: 
     ___tcf_0 in ccBdbc76.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 
+4

Đó là sự cố liên kết. Làm thế nào bạn liên kết? –

+0

Tôi mới tham gia cpp, tôi thực sự không hiểu câu hỏi của bạn. : –

+3

Bạn đã sử dụng hướng dẫn nào để biên dịch và liên kết? Trình biên dịch gì? –

Trả lời

76

Thông thường loại lỗi này xảy ra khi biên dịch mã C++ bằng cách gọi C front-end. Các gcc bạn thực hiện hiểu và biên dịch các tập tin như C + +, nhưng không liên kết nó với các thư viện C + +. Ví dụ:

$ gcc example.cpp 
Undefined symbols for architecture x86_64: 
    "std::cout", referenced from: 
     _main in ccLTUBHJ.o 
    "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from: 
     _main in ccLTUBHJ.o 
    "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from: 
     _main in ccLTUBHJ.o 
    "std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))", referenced from: 
     _main in ccLTUBHJ.o 
    "std::ios_base::Init::Init()", referenced from: 
     __static_initialization_and_destruction_0(int, int)in ccLTUBHJ.o 
    "std::ios_base::Init::~Init()", referenced from: 
     ___tcf_0 in ccLTUBHJ.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 
$ g++ example.cpp 
$ 

Như bạn có thể thấy, sử dụng g++ làm cho các vấn đề biến mất. Các hành vi tương tự (với những thông điệp hơi khác nhau) xảy ra nếu bạn sử dụng clang (mà tôi muốn khuyên):

$ clang example.cpp 
Undefined symbols for architecture x86_64: 
    "std::ios_base::Init::~Init()", referenced from: 
     ___cxx_global_var_init in cc-IeV9O1.o 
    "std::ios_base::Init::Init()", referenced from: 
     ___cxx_global_var_init in cc-IeV9O1.o 
    "std::cout", referenced from: 
     _main in cc-IeV9O1.o 
    "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from: 
     _main in cc-IeV9O1.o 
    "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from: 
     _main in cc-IeV9O1.o 
    "std::ostream::operator<<(std::ostream& (*)(std::ostream&))", referenced from: 
     _main in cc-IeV9O1.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
$ clang++ example.cpp 
$ 

Như bạn có thể thấy trong thông điệp clang lỗi, bạn có thể sử dụng -v để xem gọi mối liên kết để xem có chuyện gì vậy Nó sẽ hiển thị cho bạn dòng liên kết này:

"/usr/bin/ld" -demangle -dynamic -arch x86_64 
    -macosx_version_min 10.6.8 -o a.out -lcrt1.10.6.o 
    /var/folders/zl/zlZcj24WHvenScwjPFFFQE+++TI/-Tmp-/cc-hdOL8Z.o 
    -lSystem /Developer/usr/bin/../lib/clang/3.0/lib/darwin/libclang_rt.osx.a 

Hoặc giống như nó - bạn có thể thấy, nó liên kết thời gian chạy C chứ không phải C++ và cũng không có thư viện C++. Sử dụng clang++ dòng liên kết là:

"/usr/bin/ld" -demangle -dynamic -arch x86_64 
    -macosx_version_min 10.6.8 -o a.out -lcrt1.10.6.o 
    /var/folders/zl/zlZcj24WHvenScwjPFFFQE+++TI/-Tmp-/cc-wJwxjP.o 
    /usr/lib/libstdc++.6.dylib -lSystem 
    /Developer/usr/bin/../lib/clang/3.0/lib/darwin/libclang_rt.osx.a 

Như bạn thấy, libstdc++ được bao gồm, và mau - không có lỗi liên kết.

+10

+1 để giới thiệu clang. –

+2

dùng clang ++ làm việc. –

+2

Rất tiếc! Tôi quên thêm tập tin 'other.c' vào đối số tên tập lệnh' clang'. Tôi chỉ làm 'clang main.c'. Làm 'clang main.c other.c' hoạt động. (Tôi có '#include" other.h "' ở trên cùng của 'main.c'. – ma11hew28

3

Tôi không quen thuộc với OSX Lion. Tuy nhiên, theo nghĩa hẹp nhất, các lỗi được mô tả không phải do trình biên dịch gây ra, mà bởi trình liên kết. Dường như thư viện chuẩn không được liên kết.

3

Sử dụng lệnh CC (chữ hoa) để biên dịch C++ và liên kết tới thư viện chuẩn C++.

0

Đây có phải là GCC trên Windows (MinGW) hoặc Linux không? Trên MinGW bạn cần tham số -lmingw32 -enable-auto-import. Linux có thể cần một cái gì đó tương tự, -enable-auto-import là rất cần thiết.

+0

Câu hỏi của OP nói 'osx lion'. –

+0

Rõ ràng tôi không thể đọc -_- – Frigo

5

Hãy thử

g++ main.cpp 

Bằng cách này nó sẽ làm việc, ít nhất là sử dụng OS X

1

Tính đến Yosemite (10.10.1), tôi đã phát hiện ra rằng gcc với -lc++ cờ cũng làm việc:

gcc -lc++ main.cpp 
0

Nếu sử dụng kêu vang trên OS X, hãy thử:

clang++ simple_cpp_program_file.cpp -o simple_cpp_program_file.out 
1

Đây là giải pháp hoạt động trên macOs Sierra:

Có hai triển khai của thư viện C++ chuẩn có sẵn trên OS X: libstdC++ và libC++. Chúng không tương thích nhị phân và libMLi3 yêu cầu libstdC++.

Vào ngày 10.8 và libstdC++ trước đó được chọn theo mặc định, trên 10.9 libC++ được chọn theo mặc định. Để đảm bảo tính tương thích với libMLi3, chúng ta cần chọn libstdC++ theo cách thủ công.

Để thực hiện việc này, hãy thêm -stdlib = libstdC++ vào lệnh liên kết.

Các vấn đề liên quan