在Debian Linux中安装和链接PhysX库

时间:2009-01-06 02:47:37

标签: linux ubuntu linker debian

我正在尝试使用Ubuntu来运行PhysX。

首先,我在这里下载了SDK:


接下来,我解压缩文件并使用以下命令安装每个包:

dpkg -i filename.deb

这给了我/usr/lib/PhysX/v2.8.1中的以下文件:

  • libNxCharacter.so
  • libNxCooking.so
  • libPhysXCore.so
  • libNxCharacter.so.1
  • libNxCooking.so.1
  • libPhysXCore.so.1

接下来,我创建了/ usr / lib的符号链接:

sudo ln -s /usr/lib/PhysX/v2.8.1/libNxCharacter.so.1 /usr/lib/libNxCharacter.so.1
sudo ln -s /usr/lib/PhysX/v2.8.1/libNxCooking.so.1 /usr/lib/libNxCooking.so.1
sudo ln -s /usr/lib/PhysX/v2.8.1/libPhysXCore.so.1 /usr/lib/libPhysXCore.so.1

现在,使用Eclipse,我已经指定了以下库(-l):

  • libNxCharacter.so.1
  • libNxCooking.so.1
  • libPhysXCore.so.1

以下搜索路径以及(-L):

  • /usr/lib/PhysX/v2.8.1
  • / usr / lib中

另外,正如Gerald Kaszuba建议的那样,我添加了以下包含路径(-I):

  • /usr/lib/PhysX/v2.8.1
  • / usr / lib中

然后,我尝试编译以下代码:

#include "NxPhysics.h"

NxPhysicsSDK* gPhysicsSDK = NULL;
NxScene* gScene = NULL;
NxVec3 gDefaultGravity(0,-9.8,0);

void InitNx()
{
    gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);

    if (!gPhysicsSDK)
    {
        std::cout<<"Error"<<std::endl;
        return;
    }

    NxSceneDesc sceneDesc;
    sceneDesc.gravity = gDefaultGravity;
    gScene = gPhysicsSDK->createScene(sceneDesc);
}

int main(int arc, char** argv)
{
    InitNx();

    return 0;
}

我得到的第一个错误是:

  

NxPhysics.h:没有这样的文件或目录

这告诉我项目显然没有正确链接。任何人都可以告诉我我做错了什么,或者我需要做些什么来让我的项目编译?我正在使用GCC C ++编译器。提前谢谢!

3 个答案:

答案 0 :(得分:2)

看起来你将头文件与库文件混淆了。 NxPhysics.h是源代码头文件。编译源代码时(而不是链接时)需要头文件。它可能位于/ usr / include或/usr/include/PhysX/v2.8.1等类似的地方。找到这个文件的真实位置,并确保使用-I选项告诉编译器它在哪里,正如Gerald Kaszuba建议的那样。

链接编译的目标文件时(而不是编译时)需要库。稍后您需要使用-L和-l选项处理此问题。

注意:根据你调用gcc的方式,你可以让它进行编译然后用单个调用进行链接,但是在幕后它仍然会进行编译步骤然后进行链接步骤。


编辑:添加了额外的解释......

使用C / C ++编译器构建二进制文件时,编译器会读取源代码(.c或.cpp文件)。在阅读它时,经常会有#include语句用于读取.h文件。 #include语句给出了必须加载的文件的名称。那些确切的文件必须存在于包含路径中。在您的情况下,必须在包含路径中的某处找到具有确切名称“NxPhysics.h”的文件。通常,/ usr / include默认位于路径中,当前目录也是如此。如果标题位于其他位置(例如/ usr / include的子目录),那么您始终需要使用-I命令行开关(或者有时使用环境变量或其他系统配置方法)明确告诉编译器在哪里查找。

<。> .h头文件通常包括数据结构声明,内联函数定义,函数和类声明以及#define宏。编译完成后,将创建.o对象文件。编译器不知道.so或.a库,也不能以任何方式使用它们,除了为链接器嵌入一些辅助信息。请注意,编译器还会在目标文件中嵌入一些“标题”信息。我将“标题”放在引号中,因为该信息仅大致对应于.h文件中可能找到或未找到的内容。它包括所有导出声明的二进制表示。那里找不到宏。我相信内联函数也被省略(虽然我可能在那里错了)。

一旦存在所有.o文件,就需要另一个程序接管:链接器。链接器不知道源代码文件或.h头文件。它只关心二进制库和目标文件。你给它一个库和目标文件的集合。在他们的“标题”中,他们列出了他们定义的内容(数据类型,函数等)以及他们需要别人定义的内容。然后,链接器将来自一个模块的定义请求与其他模块的实际定义进行匹配。它会检查以确保没有多个冲突的定义,如果构建可执行文件,它会确保满足所有定义请求。

以上描述有一些值得注意的警告。首先,可以调用gcc一次并让它进行编译和链接,例如

gcc hello.c -o hello

首先将hello.c编译到内存或临时文件,然后它将链接到标准库并写出hello可执行文件。尽管只有一次调用gcc,但为了方便起见,这两个步骤仍然是按顺序执行的。我暂时会跳过描述动态库的一些细节。

如果你是Java程序员,那么上面的一些可能会有点混乱。我相信.net的工作方式与Java类似,因此以下讨论应该适用于C#和其他.net语言。 Java在语法上是一种比C和C ++更简单的语言。它缺少宏,缺乏真正的模板(泛型是一种非常弱的模板形式)。因此,Java不需要单独的声明(.h)和定义(.c)文件。它还能够将所有相关信息嵌入到目标文件中(.class for Java)。这使得编译器和链接器都可以直接使用.class文件。

答案 1 :(得分:0)

问题确实在于我的包含路径。以下是相关命令:

g++ -I/usr/include/PhysX/v2.8.1/SDKs/PhysXLoader/include -I/usr/include -I/usr/include/PhysX/v2.8.1/LowLevel/API/include -I/usr/include/PhysX/v2.8.1/LowLevel/hlcommon/include -I/usr/include/PhysX/v2.8.1/SDKs/Foundation/include -I/usr/include/PhysX/v2.8.1/SDKs/Cooking/include -I/usr/include/PhysX/v2.8.1/SDKs/NxCharacter/include -I/usr/include/PhysX/v2.8.1/SDKs/Physics/include -O0 -g3 -DNX_DISABLE_FLUIDS -DLINUX -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"

此外,对于链接器,只需要“PhysXLoader”(与Windows相同)。因此,我有:

g++  -o"PhysXSetupTest"  ./main.o   -lglut -lPhysXLoader

答案 2 :(得分:0)

安装时出现以下错误 *

dpkg: dependency problems prevent configuration of libphysx-dev-2.8.1:
 libphysx-dev-2.8.1 depends on libphysx-2.8.1 (= 2.8.1-4); however:
  Package libphysx-2.8.1 is not configured yet.
dpkg: error processing libphysx-dev-2.8.1 (--install):
 dependency problems - leaving unconfigured
Errors were encountered while processing:

* 所以我重新安装了* libphysx-2.8.1_4_i386.deb *

sudo dpkg -i libphysx-2.8.1_4_i386.deb