对不起,如果这是一个显而易见的问题,但我发现很少有人在网上引用...
我正在使用我们的业务合作伙伴用C编写的API,并将其作为.so二进制文件提供给我们,构建在Fedora 11上.我们已经在Fedora 11开发机器上测试了API,没有任何问题.但是,当我尝试链接客户目标平台上的API(恰好是SuSE Enterprise 10.2)时,我收到"文件格式无法识别"错误.
同样属于binutils包的命令,例如objdump或nm,给出了相同的文件格式错误."file"命令显示我:
ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped
Run Code Online (Sandbox Code Playgroud)
并且"ldd"命令显示:
ldd: warning: you do not have execution permission for `./libuscuavactivity.so.1.1'
./libuscuavactivity.so.1.1: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./libuscuavactivity.so.1.1)
[dependent library list]
Run Code Online (Sandbox Code Playgroud)
我猜这是由于两个平台上的C库之间不兼容,问题是代码是针对新版本的glibc等而不是SuSE 10.2上提供的.我发布这个问题是因为有一种方法可以在我们的合作伙伴的Fedora 11平台上编译代码,这样它也可以在SuSE 10.2上运行.
我想用来自Linux标准库http://www.linuxfoundation.org/collaborate/workgroups/lsb的 LSB C++编译器构建我的程序.程序取决于使用gcc 4.4版本构建的Boost库.编译失败.是否可以使用LSB C++编译器构建Boost库?或者,是否可以使用一些旧的gcc版本构建Boost库,建议使用什么版本?我的最终目标是让我的可执行文件和第三方Boost库在大多数Linux发行版上运行.
通常,可以采取哪些措施来获得更好的Linux发行版二进制兼容性,根据Boost库开发C++闭源应用程序?
在白天的工作中,我使用VB6(我知道,但不要模拟受影响的......)应用程序,它使用了我们编写的许多库(也是在着名的VB6中).其中一个支持库有大量私有成员通过公共属性公开,我被要求删除属性,并将私有成员变量提升到与原始属性同名的公共字段.
现在,我不是COM专家,但我的印象是,类中的每个暴露项都获得了它自己的GUID.因为我们将从每个值从2个Guids(Property Get和Property Let)变为仅使用一个(公共字段)的情况开始,我期望这会破坏二进制兼容性 - 但它似乎没有做到了.
有谁能解释为什么?
初步说明:问题提到AIX,因为它是初始上下文,但问题确实与gcc本身有关,很可能与平台无关.
AIX应该是向后二进制兼容的:在AIX 5.1上编译的C程序将在5.2,5.3,6.1和7.1上运行.
在我的理解中,应该构建gcc以针对特定系统(在交叉编译的情况下是当前的一个还是另一个).因此,基于AIX 6.1构建的gcc以AIX 6.1为目标,并且由于二进制兼容性,生成可在6.1和7.1上使用的二进制文件.
然而,在AIX 6.1上构建的gcc本身就是一个6.1程序,所以它应该在7.1上执行.当然如果我在7.1上用它编译程序,这个程序可能会被链接或使用特定于7.1的头文件,从而使得生成的二进制文件需要7.1.因此,据我所知,我应该能够将在AIX 6.1上构建的gcc运行到7.1机器上,并生成可能非最佳且完全有效的二进制文件,尽管它们需要7.1作为链接的副作用.
这看起来太像彩虹和独角兽在闪闪发光的天空中跳舞.我闻到了一些可疑的东西但却缺乏gcc内脏的知识.请强大的人群,赐教.
tl; dr:gcc是否可以构建并针对OS /平台的N版本运行,并且由于平台二进制兼容性而在版本N + 1上使用以生成在N + 1版本上运行的二进制文件?如果没有,什么机制会阻止它?
我试图编译一个开源项目的二进制文件,以便我们的用户不必自己编译它.
我注意到在一台32位ubuntu机器"A"上创建的一些二进制文件在32位机器"B"上不起作用,并且报告了丢失.so文件的错误.
但是,如果我在机器"B"上从头开始编译,那么所有错误都消失了.
是否有任何理由为什么编译目标机器上的代码会使这些错误消失?我只运行"./configure"和"make" - 而不是"make-install",所以它不像我在全球范围内制作这些.so文件.
可能是编译器检测到系统库中缺少.so文件,在这种情况下将静态库链接到可执行文件中?
Ubuntu如何编译其软件包以便在所有x86机器上运行i386软件包?
我最初使用VC9.0在win7 32位上设计了一个win32应用程序.我最近升级到win7 64位,并尝试构建+执行以前的应用程序.
构建运行正常(win32应用程序),但在运行时我得到错误"[...]退出代码-1073741701(0xc000007b)."
我想这是加载64位版本[预期] 32位dll的结果.
此项目的特定依赖项是:SDL.lib SDLmain.lib SDL_ttf.lib opengl32.lib glu32.lib wininet.lib
SDL和SDL_ttf仅为32位版本.我假设Visual Studio足够聪明,可以在我请求win32应用程序时获取\ syswow64中的opengl和glu lib文件.
可能是因为wininet?或者我犯了错误?
谢谢,
我正在阅读"实用API设计"并找到以下段落:
" 可以在JVM规范中找到优先使用字段的方法的另一个原因.您可以将方法从类移动到其超类之一,并且仍然保持二进制兼容性.因此,最初作为Dimension javax.swing引入的方法.JComponent.getPreferredSize(Dimension d)可以在新版本中删除并移动到Dimension java.awt.Component.getPreferredSize(Dimension d),因为JComponent是Component的子类.这样的更改确实发生在JDK 1.2中,并且这可以仅仅因为字段被方法封装而完成.对于字段不允许这样的操作.一旦在类中定义字段,它必须永远保持在那里以保持二进制兼容性,这是另一个原因保持字段私密 "
因为我同意使用getter/setter是更好的方法.但是我不明白为什么将公共字段移到父类会打破二进制兼容性?您仍然可以通过子类访问该字段,只要它在父级中是公共的.
当我尝试重建我的一个VB6 DLL时,我收到一个警告:
"二进制兼容性DLL或EXE包含无法找到其定义的参数类型或返回类型"
我要释放的DLL选择一些变化(简单的改变内部的方法-没有什么根据打破了兼容性本)
我所遵循的普遍接受的方法是将旧的DLL保存在单独的共享目录中,并在制作新的DLL时,使用设置为旧的DLL集的二进制兼容性来编译它们.这样做是为了在我注册新DLL时不更改GUID.这些GUID在其他DLL中用作引用,我在发布过程中没有受到干扰.
我很确定我没有添加任何东西来打破二进制兼容性规则(签名,公共方法,变量等没有变化)为什么会出现这个错误?
我不是一个基本的东西,我是一个菜鸟吗?从早上起我的头.任何帮助深表感谢.
编辑:如果我的签名发生了变化,有没有一种方法可以在不比较代码的情况下知道?
我有一个关于二进制兼容性的问题.我有一个类A,它包含一个公共方法foo()和一个属性字符串_foo;
const string foo() {return _foo;}
Run Code Online (Sandbox Code Playgroud)
当我改为
const string& foo(){return _foo;}
Run Code Online (Sandbox Code Playgroud)
它仍然是二进制兼容的吗?谢谢你的帮助!
我遇到了以下奇怪的Java/JVM规范不完整的情况.假设我们有类(我们将使用Java 1.8和HotSpot):
public class Class {
public static void foo() {
System.out.println("hi");
}
}
public class User {
public static void main(String[] args) {
Class.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
然后重新编译Class to be an interface without recompiling theUser`:
public interface Class {
public static void foo() {
System.out.println("hi");
}
}
Run Code Online (Sandbox Code Playgroud)
运行User.mainnow会产生相同的输出hi.这似乎是显而易见的,但我希望它会失败,IncompatibleClassChangeError这就是为什么:
我知道根据JVM 5.3.5#3语句将类更改为接口是二进制不兼容:
如果命名为C的直接超类的类或接口实际上是一个接口,则加载会抛出一个
IncompatibleClassChangeError.
但是我们假设我们没有继承者Class.我们现在必须参考JVM规范来了解方法的分辨率.第一个版本被编译成这个字节码:
public static void main(java.lang.String[]);
Code:
0: invokestatic #2 // Method examples/Class.foo:()V
3: return
Run Code Online (Sandbox Code Playgroud)
所以我们这里有一个叫做 …