Tuesday, 22 November 2022

Python/C++ Extension, Undefined symbol error when linking a library

I made a project that has glfw as a library, my directory looks like this:

main_dir
|--include
|--|--glfw_binder.h
|--src
|--|--glfw_binder.cpp
|--lib
|--|--glfw
|--|--|--src
|--|--|--|--libglfw.so
|--|--|--|--libglfw.so.3
|--|--|--|--libglfw.so.3.3
|--|--|--|--...
|--|--|--include
|--|--|-- ...
|--main.cpp
|--setup.py
|--test.py

I've installed glfw from its website and simply extracted it to lib/ directory. Then I ran cmake -G "Unix Makefiles" followed by make to build it.

When I try to run it as pure C++ with this cmake file it runs just fine, it displays the glfw window:

cmake_minimum_required(VERSION 3.0)
project(Test)

add_subdirectory(lib/glfw)

find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_executable(Test main.cpp src/glfw_binder.cpp)

target_link_libraries(Test PRIVATE 
    ${PYTHON_LIBRARIES}
    glfw
)

And here is what my setup.py looks like:

from setuptools import setup, Extension, find_packages

module1 = Extension('test',
                    sources = ['main.cpp', 'src/glfw_binder.cpp'],
                    include_dirs=["include", "lib/glfw/include"],
                    library_dirs=["lib/glfw"],
                    libraries=["lib/glfw"],
                    extra_link_args=["lib/glfw"]
                    )

setup (name = 'python_test',
       version = '1.0',
       description = 'This is a demo package',
       packages=find_packages("glfw"),
       ext_modules = [module1]
       )

Then I run python3 setup.py build followed by sudo python3 setup.py install. It creates the so files just fine. Then I run this test code:

import test

test.create_glfw_window()

When I run this script via python3 test.py I got this error:

Traceback (most recent call last):
  File "/home/turgut/Desktop/TestDir/Python-Binder-Test/test.py", line 3, in <module>
    import test
ImportError: /usr/local/lib/python3.10/dist-packages/python_test-1.0-py3.10-linux-x86_64.egg/test.cpython-310-x86_64-linux-gnu.so: undefined symbol: glfwDestroyWindow

It's not specific to glfwDestroyWindow it says this for all glfw functions. How am I supposed to link this?

Update: I've added these lines:

       packages=['glfw'],
       package_dir={'glfw': 'lib/glfw'},
       #package_data={'glfw': ['lib/glfw/src/*.so']},
       package_data={'glfw': ['lib/glfw/src/libglfw.so', "lib/glfw/src/libglfw.so.3", "lib/glfw/src/libglfw.so.3.3"]},

Now it gives me the following error:

ImportError: libglfw.so.3: cannot open shared object file: No such file or directory

Even though I've specified all the .so files together. I don't think this is the way to go but I thought it's worth mentioning.

Better update: I've removed the above update and added these two lines to my extension:

include_dirs=["include", "lib/glfw/include"],
       #extra_link_args=[ "-lm", "-lGL", "-lGLU", "-lglfw"],
       library_dirs=["lib/glfw"],
       libraries=['glfw']

and now I'm getting this error which I think is closer to what I'm looking for:

/usr/bin/ld: cannot find -lglfw: No such file or directory
collect2: error: ld returned 1 exit status
error: command '/usr/bin/x86_64-linux-gnu-g++' failed with exit code 1


from Python/C++ Extension, Undefined symbol error when linking a library

No comments:

Post a Comment