Iss*_* T. 17 c++ macos linker static-libraries 32bit-64bit
编辑:
如果你落在这篇文章上,你可能想直接跳到答案
今天早上我发了一篇关于我的困惑的帖子
机器类型(C++ librairies):i386 vs x86_64
但我想我做错了不准确.所以我决定举一个我面对的情况的例子,我无法理解.
步骤1
我在机器A上构建了一个库,一个2岁的mac,OS x 10.7.5(我猜是64位;我的猜测基于你将在下面的附加信息中看到的命令)使用以下文件.
标题SimpleClass.hpp:
#ifndef SIMPLECLASS_HPP
#define SIMPLECLASS_HPP
class SimpleClass
{
public:
SimpleClass();
SimpleClass(const SimpleClass& orig);
virtual ~SimpleClass();
private:
} ;
#endif /* SIMPLECLASS_HPP */
Run Code Online (Sandbox Code Playgroud)
源文件SimpleClass.cpp:
#include "SimpleClass.h"
#include <iostream>
SimpleClass::SimpleClass()
{
std::cout << "A new instance of Simple Class was created" << std::endl;
}
SimpleClass::SimpleClass(const SimpleClass& orig)
{
}
SimpleClass::~SimpleClass()
{
}
Run Code Online (Sandbox Code Playgroud)
我使用创建库
~/cpp_test$ clang++ -c -o SC.o -I SimpleClass.hpp SimpleClass.cpp
~/cpp_test$ ar rcs libtest_sc.a SC.o
Run Code Online (Sandbox Code Playgroud)
机器A的其他信息:
~/cpp_test$ clang++ --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin11.4.2
~/cpp_test$ uname -m
x86_64
~/cpp_test$ uname -p
i386
~/cpp_test$ lipo -info libtest_sc.a
input file libtest_sc.a is not a fat file
Non-fat file: libtest_sc.a is architecture: x86_64
Run Code Online (Sandbox Code Playgroud)
第2步
我将SimpleClass.hpp以及库复制到另一台机器B,这是一台5年前使用osx 10.6.7的Mac机器,我认为它是32位.我编写以下hello文件来测试库
#include <iostream>
#include "SimpleClass.hpp"
int main()
{
std::cout << "Hello World!" << std::endl;
SimpleClass testObj;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,我没有遇到与图书馆链接的问题.
[~/Downloads/Gmail-9]$ g++ -o hello -L. -ltest_sc hello.cpp
[~/Downloads/Gmail-9]$ ./hello
Hello World!
A new instance of Simple Class was created
Run Code Online (Sandbox Code Playgroud)
机器B的其他信息:
[~/Downloads/Gmail-9]$ uname -m
i386
[~/Downloads/Gmail-9]$ uname -p
i386
[~/Downloads/Gmail-9]$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)
第3步
我在Machine C上使用相同的头文件和hello文件再次复制相同的库,这是一个10.9.2的新mac,我相信是64位.
令人惊讶的是我有链接问题
MacBook-Pro:testcpp$ g++ -o hello -L. -ltest_sc hello.cpp
Undefined symbols for architecture x86_64:
"std::ostream::operator<<(std::ostream& (*)(std::ostream&))", referenced from:
SimpleClass::SimpleClass() in libtest_sc.a(SC.o)
"std::ios_base::Init::Init()", referenced from:
___cxx_global_var_init in libtest_sc.a(SC.o)
"std::ios_base::Init::~Init()", referenced from:
___cxx_global_var_init in libtest_sc.a(SC.o)
"std::cout", referenced from:
SimpleClass::SimpleClass() in libtest_sc.a(SC.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:
SimpleClass::SimpleClass() in libtest_sc.a(SC.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:
SimpleClass::SimpleClass() in libtest_sc.a(SC.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
关于机器C的其他信息
g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
MacBook-Pro:testcpp$ uname -m
x86_64
MacBook-Pro:testcpp$ uname -p
i386
Run Code Online (Sandbox Code Playgroud)
我本以为机器B的连接问题是32位而不是机器C是64位,但我却反其道而行之.谁能解释一下我在这里缺少什么?
编辑(第4步)
在机器C上,当我向g++
命令添加选项时-stdlib=libstdc++
,"未定义符号"错误消失,可执行文件正确运行.运行G ++与-v让我注意到默认选项stdlib
是libc++
不libstdc++
.因此,虽然机器A和机器C都是64位,但stdlib
默认情况下它们不会使用相同的错误导致错误Undefined symbols for architecture x86_64
.
Iss*_* T. 21
我所有的问题都在给予
Undefined symbols for architecture x86_64
是因为某些库是用libstdc ++编译的,不能用于用libc ++编译/链接的代码
libc ++实际上是自Mavericks以来clang使用的默认新库,但是可以通过使用选项使用相同的clang(不需要安装旧的gcc)与经典的libstdc ++进行编译
-stdlib=libstdc++
对于那些使用Boost的人来说,通过下载源代码并使用(编译时)而不是经典代码,也可以在libverdc ++编译/链接的小牛上使用boost库
./b2
下列
./b2 cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++"
对于那些使用Cmake的人,您可能希望在适当的cmake文件中添加类似于:
find_library (LIBSTDCXX NAMES stdc++)
和
add_compile_options(-stdlib=libstdc++)
和
target_link_libraries(${PROJECT_NAME} ${LIBSTDCXX} ${YOUR_OTHER_LIBRARIES))
归档时间: |
|
查看次数: |
36948 次 |
最近记录: |