Incorrect name mangling for std::string in panda SDK OSX (how to compile LUI on MacOS)

I’m currently trying to get a very small example compiled on macOS using the manual entry:
https://www.panda3d.org/manual/?title=How_to_compile_a_C++_Panda3D_program_on_macOS

But I am running into a problem with what I think is abi compatibility to the stdlib used to compile the panda SDK that I’m using.

The command line commands I’m using to compile are:

clang++ \
    -I/Developer/Panda3D/include \
    -I/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/include/python3.7m \
    -std=gnu++11 \
    -o foo.cpp.o \
    -c foo.cpp

clang++ \
    foo.cpp.o \
    -L/Developer/Panda3D/lib \
    -lp3framework \
    -lpanda \
    -lpandaexpress \
    -lp3dtoolconfig \
    -lp3dtool \
    -lp3pystub \
    -lp3direct

And the example program is:

#include "internalName.h"


int main(void)
{
    const std::string prefix("lui_texture_");
    int i = 0;
    InternalName::make(prefix, i);

    return 0;
}

I’m getting the error:

Undefined symbols for architecture x86_64:
  "InternalName::make(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
      _main in foo.cpp.o
ld: symbol(s) not found for architecture x86_64

My compiler:

$ clang++ --version
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

My OS:

macOS Mojave 10.14.6

I’m using the panda SDK 1.10.4.1 from the website.

Has anyone encountered this before and could chime in on what might be going wrong? The symbol is located in /Developer/Panda3D/lib//libpanda.dylib with the symbol:

$ c++filt __ZN12InternalName4makeERKSsi
InternalName::make(std::string const&, int)

Yes, I have encountered the same problem :slight_smile:

Panda SDK is compiled against an old version of Xcode (targeting osx 10.6 if I remember correctly) and that version of Xcode uses libstdc++ on the other hand apple has switched to libc++ (I think since Mojave) hence the problem when you link your code compiled with libc++ name mangling it except that the Panda SDK also uses it.

Two solutions: recompile Panda and it’s dependencies on your system (I think there is an issue on github related to that) or download an old version of Xcode and use the provided libstdc headers to compile your code. That’s the solution I’m using right now.
If interested I could retrieve the arguments to use.

Alright good to know I wasn’t far off. I would appreciate it if you could post the arguments. Thanks!

Here are the parameters for CMake:

For the compiler:

add_definitions("-stdlib=libstdc++") 
include_directories("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/usr/include/c++/4.2.1")

You can use -I for the latter if you use Make instead.

For the linker:

target_link_options(${PROJECT_NAME} PUBLIC "-stdlib=libstdc++")
target_link_options(${PROJECT_NAME} PUBLIC "-Wl,-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk//usr/lib/i686-apple-darwin11/4.2.1/")

For the Xcode to use I’m on my phone and don’t have the link here but I think version 4.2.1 is the one to use

Okay I couldn’t get an older mac SDK to work, so I went the route of compiling everything with a more modern compiler. Here’s how I did it:

# Install some requirements beforehand. There may be more which I already had installed.
brew install yasm
brew install icu4c
brew install python3
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig"

# Building panda-thirdparty - these are required to build the Panda3D SDK. I skipped bullet because I can't get it to compile.
git clone https://github.com/treamology/panda3d-thirdparty.git
cd panda3d-thirdparty
# This is important! This branch has the changes needed for newer versions of MacOS.
git checkout ios
mkdir build
cd build
# NOTE: the output will be in ../darwin-libs-a
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_BULLET:BOOL=FALSE ..
cmake --build . --config Release

# Go back to the top level.
cd ../../

# Building panda
git clone https://github.com/panda3d/panda3d.git
cd panda3d

# Copy the third party stuff over to here.
mkdir thirdparty
cp -R ../panda3d-thirdparty/darwin-libs-a thirdparty/

# You might need to change your osxtarget depending on your MacOS version.
python3 makepanda/makepanda.py --everything --no-bullet --osxtarget 10.15 --threads 4 --python-incdir=/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/include --python-libdir=/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib --installer

# Go back to the top-level directory.
cd ..

# Now you have an installer for the Panda3D SDK. You need to do a couple of things to install it (especially if you are using MacOS 10.15 which makes the root directory read-only).

# 1. open disk utility
# 2. Click file -> New Image -> Blank Image
# 3. Name it PandaSDK-1_11_0
# 4. Set size to 1 GB
# 5. Click save and it should be mounted automatically but if it isn't, then mount it.
# 6. Run your new Panda3D SDK installer, and when you get to the drive selection, select your volume you just created.
# 7. VERY IMPORTANT select back and make sure to check to install the headers. Whenever you change the drives it will uncheck that option...

# Now that you have the SDK installed, we can finally compile lui.
git clone https://github.com/tobspr/LUI.git
cd LUI
python3 update_module_builder.py
VERBOSE=1 PYTHONPATH=/Volumes/PandaSDK-1_11_0/Developer/Panda3D python3 build.py

# Finally you should have lui.so compiled, now we just need to add it to the sdk.
cp osx_amd64_panda1.11.0_py37/lui.so /Volumes/PandaSDK-1_11_0/Developer/Panda3D/panda3d/

# Now make python find the panda python files and try importing lui.
export PYTHONPATH=/Volumes/PandaSDK-1_11_0/Developer/Panda3D python3 -c "import panda3d.lui"

# Great! Now you have LUI compiled! A couple of gotchas:
# 1. A lot of the LUI code uses unicode(). If you're in python3, you need to replace this with str().
# 2. IMPORTANT!!! In your prc file for panda you need
#	gl-version 3 2
#
#	For example:
#		from panda3d.core import load_prc_file_data
#		load_prc_file_data("", """
#		    text-minfilter linear
#		    text-magfilter linear
#		    text-pixels-per-unit 32
#		    sync-video #f
#		    textures-power-2 none
#		    show-frame-rate-meter #t
#		    win-size 700 600
#		    window-title LUI Minimal Example
#		    gl-version 3 2
#		""")
#	If you forget this, then LUI won't render correctly.

If anyone uses this and runs into problems let me know so I can update it. I made this by copying things from my bash history, so there could be a small mistake somewhere. :slight_smile: