Difference between revisions of "64-bit Migration"

From X-Plane SDK
Jump to: navigation, search
(OS X Linker Settings)
(Correct "nm" Output)
 
(10 intermediate revisions by 2 users not shown)
Line 7: Line 7:
 
On OS X you have two options: you can build a plugin with multiple architectures (the standard way to build a 'universal' plugin on OSX) or you can simply build two binaries and put them in the 32 and 64 folders above.  The choice is yours; one option may be easier depending on the project settings of your particular plugin.
 
On OS X you have two options: you can build a plugin with multiple architectures (the standard way to build a 'universal' plugin on OSX) or you can simply build two binaries and put them in the 32 and 64 folders above.  The choice is yours; one option may be easier depending on the project settings of your particular plugin.
  
= Update to the 2.1.1 SDK =
+
= Update to the 2.1.2 SDK =
  
If your plugin does not already use the new 2.1.1 SDK, update to this SDK now.
+
If your plugin does not already use the new 2.1.2 SDK, update to this SDK now.
  
 
* Download the new SDK libraries and headers from the SDK website.
 
* Download the new SDK libraries and headers from the SDK website.
 
* If your plugin used the 1.x or 2.0.x SDK, you will need to replace "long" with "intptr_t" or "int" in your widget and data ref callbacks - simply make the right substitution to fix compile errors.  You can look up the 'right' syntax in the docs.
 
* If your plugin used the 1.x or 2.0.x SDK, you will need to replace "long" with "intptr_t" or "int" in your widget and data ref callbacks - simply make the right substitution to fix compile errors.  You can look up the 'right' syntax in the docs.
 
* If your plugin used XPCAircraft (as part of libxplanemp), copy it from an old SDK into your project - it should not have been part of the X-Plane SDK distribution.
 
* If your plugin used XPCAircraft (as part of libxplanemp), copy it from an old SDK into your project - it should not have been part of the X-Plane SDK distribution.
 +
* Mac users: you will want to start linking against the new frameworks - see below.
  
 
= Get New Libraries =
 
= Get New Libraries =
Line 33: Line 34:
  
 
For MSVC, you will need to first change the platform SDK to Windows 7.1 (the default might be v100).  If you don't have this, install the Windows 7.1 platform SDK.  Then add a new platform to your project using the configuration manager - add x64.  You can now compile both x64 (64-bit) and win32 (32-bit) plugins.
 
For MSVC, you will need to first change the platform SDK to Windows 7.1 (the default might be v100).  If you don't have this, install the Windows 7.1 platform SDK.  Then add a new platform to your project using the configuration manager - add x64.  You can now compile both x64 (64-bit) and win32 (32-bit) plugins.
 +
 +
For both Linux and OS X, -fvisibility=hidden should be passed to the compiler.  (For X-Code, check 'symbols hidden by default'.)  You should ''still'' use the linking advice below!
  
 
= Change linker settings to 64-bit =
 
= Change linker settings to 64-bit =
Line 48: Line 51:
 
== Linux Linker Settings ==
 
== Linux Linker Settings ==
  
LINUX: use the linker script option listed under "gcc 3" in the linking instructions - this technique actually works on ALL versions of GCC and always produces a clean plugin:
+
Be sure to use a version script to remove symbols from your plugin.
  
 
Use --version-script=<text file> to ld lets you send a linker script. One of the form
 
Use --version-script=<text file> to ld lets you send a linker script. One of the form
Line 63: Line 66:
 
  };
 
  };
  
 +
'''C++ Note:''' if your plugin normally defines an _init and _fini symbol, add these to the "global" list above - they are necessarys for C++ global object setup.
 +
 +
'''WARNING:''' if you use global C++ objects, be sure their constructors do not call any XPLM routines - it is illegal to call the XPLM outside one of the official callbacks!!
  
 
== OS X Linker Settings ==  
 
== OS X Linker Settings ==  
Add this to the "Other linker flags":
 
  
-Wl,-exported_symbol -Wl,XPluginStart -Wl,-exported_symbol -Wl,XPluginEnable
+
There are major changes to how you link OS X plugins for the 2.1.2 SDK:
-Wl,-exported_symbol -Wl,XPluginReceiveMessage -Wl,-exported_symbol -Wl,XPluginDisable
+
 
  -Wl,-exported_symbol -Wl,XPluginStop
+
* Remove the options -flat_namespace and -undefined warning - you don't need them!
 +
* Add XPLM.framework and XPWidgets.framework to your X-Code project.
 +
* Add the architectures you want to compile for to the architectures setting in X-code, e.g. x86_64.
 +
 
 +
== Correct "nm" Output ==
 +
 
 +
This listing shows correct nm output for testing linkage on Mac/Linux. (Thanks to BSUB for providing is linker output as an example!)
 +
 
 +
'''Linux''': if your plugin is stripped, use
 +
  nm -D lin.xpl
 +
 
 +
What symbols are exported?
  
 +
Bob-Feavers-Computer-487:64 bfeaver$ nm mac.xpl | grep "T "
 +
0000000000000f66 T _XPluginDisable
 +
0000000000000f6c T _XPluginEnable
 +
0000000000003e86 T _XPluginReceiveMessage
 +
0000000000004117 T _XPluginStart
 +
0000000000003eb9 T _XPluginStop
  
You can put all of the flags on one line or put one on each line in X-code. If you use multiple lines in the X-Code UI make sure they are in consecutive order.
+
Note that only the "big 5" callbacks are exported! No static library functions and no internal symbols!
  
 
[[Category:Tech Notes]]
 
[[Category:Tech Notes]]

Latest revision as of 02:35, 16 January 2013

This tech note describes the steps to porting a plugin to 64-bits. For more info on 64-bit plugins, see here.

Fat Plugins and 64-bit

The rest of this tech note describes how to build a 64-bit only plugin. To build a 'fat' plugin that runs on 32-bit and 64-bit X-Plane, you simply build two plugins (one the same way as you did before, and one using these new instructions). Put the 32-bit builds (for each OS) in a folder called "32" and the 64-bit builds (fore act OS) in a folder called "64".

On OS X you have two options: you can build a plugin with multiple architectures (the standard way to build a 'universal' plugin on OSX) or you can simply build two binaries and put them in the 32 and 64 folders above. The choice is yours; one option may be easier depending on the project settings of your particular plugin.

Update to the 2.1.2 SDK

If your plugin does not already use the new 2.1.2 SDK, update to this SDK now.

  • Download the new SDK libraries and headers from the SDK website.
  • If your plugin used the 1.x or 2.0.x SDK, you will need to replace "long" with "intptr_t" or "int" in your widget and data ref callbacks - simply make the right substitution to fix compile errors. You can look up the 'right' syntax in the docs.
  • If your plugin used XPCAircraft (as part of libxplanemp), copy it from an old SDK into your project - it should not have been part of the X-Plane SDK distribution.
  • Mac users: you will want to start linking against the new frameworks - see below.

Get New Libraries

If your code uses third party libraries like libpng, libcurl, etc. you will need to get versions of these libraries that ship in both 32 and 64-bit ABIs.

Fix 64-bit Code Issues

If you have any code that won't run with 64-bit compilation, fix that now.

  • You cannot cast a ptr to an int and back in 64-bits. Use intptr_t if you need an int that is the size of a ptr.
  • Don't use "long" for cross-platform code; the treatment of "long" varies by compiler.

Change compile settings to 64-bit

On Linux, and Windows using GCC-based compilers use -m64 and -m32 to set the compilation mode.

For X-Code/Mac use -arch i386 and -arch x86_64 or put the string "i386 x86_64" into the architecture property of your project.

For MSVC, you will need to first change the platform SDK to Windows 7.1 (the default might be v100). If you don't have this, install the Windows 7.1 platform SDK. Then add a new platform to your project using the configuration manager - add x64. You can now compile both x64 (64-bit) and win32 (32-bit) plugins.

For both Linux and OS X, -fvisibility=hidden should be passed to the compiler. (For X-Code, check 'symbols hidden by default'.) You should still use the linking advice below!

Change linker settings to 64-bit

For Windows, link against XPLM_64.lib and XPWidgets_64.lib for the 64-bit build; link against XPLM.lib and XPWidgets.lib for the 32-bit build. If you have static libs, you will need to link against the 64-bit variant. Note that the OS libs (e.g. opengl) are named the same (opengl32.dll, for example) for 64-bit AND 32-bit.

On Mac and Linux, you may need to change which libraries you pass to your plugin, passing 64-bit libs or 32-bit libs depending on the build type.

IMPORTANT: make sure your namespace is "clean" on OSX and Linux. If you do this:

nm mac.xpl | grep "T "

The only symbols listed should be the five plugin functions (XPluginStart, XPluginEnable, XPluginReceiveMessage, XPluginDisable, and XPluginStop). If any other symbols are visible, change your linking settings to the new recommended techniques:

Linux Linker Settings

Be sure to use a version script to remove symbols from your plugin.

Use --version-script=<text file> to ld lets you send a linker script. One of the form

{
 global:
  XPluginStart;
  XPluginStop;
  XPluginEnable;
  XPluginDisable;
  XPluginReceiveMessage;
 local:
   *;
};

C++ Note: if your plugin normally defines an _init and _fini symbol, add these to the "global" list above - they are necessarys for C++ global object setup.

WARNING: if you use global C++ objects, be sure their constructors do not call any XPLM routines - it is illegal to call the XPLM outside one of the official callbacks!!

OS X Linker Settings

There are major changes to how you link OS X plugins for the 2.1.2 SDK:

  • Remove the options -flat_namespace and -undefined warning - you don't need them!
  • Add XPLM.framework and XPWidgets.framework to your X-Code project.
  • Add the architectures you want to compile for to the architectures setting in X-code, e.g. x86_64.

Correct "nm" Output

This listing shows correct nm output for testing linkage on Mac/Linux. (Thanks to BSUB for providing is linker output as an example!)

Linux: if your plugin is stripped, use

nm -D lin.xpl

What symbols are exported?

Bob-Feavers-Computer-487:64 bfeaver$ nm mac.xpl | grep "T "
0000000000000f66 T _XPluginDisable
0000000000000f6c T _XPluginEnable
0000000000003e86 T _XPluginReceiveMessage
0000000000004117 T _XPluginStart
0000000000003eb9 T _XPluginStop

Note that only the "big 5" callbacks are exported! No static library functions and no internal symbols!