Getting linking error when using methods that take glm:: in CesiumGeospatial on Android (solved)

I am building cesium-native static libraries for Android, but getting a linker error when trying to call the Cesium3DTilesSelection::ViewState::create(...) static method.

auto viewState = Cesium3DTilesSelection::ViewState::create(glm::dvec3(positionx, positiony, positionz),
                                            glm::dvec3(directionx, directiony, directionz),
                                            glm::dvec3(upx, upy, upz),
                                            glm::dvec2(viewportSizex, viewportSizey),
                                            hfov, vfov);

This compiles fine, but fails during linking. Other methods in the library link fine. Calling the same method from our Windows build works fine. The specific error we see is:

ld: error: undefined symbol: Cesium3DTilesSelection::ViewState::create(glm::vec<3, double, (glm::qualifier)0> const&, glm::vec<3, double, (glm::qualifier)0> const&, glm::vec<3, double, (glm::qualifier)0> const&, glm::vec<2, double, (glm::qualifier)0> const&, double, double, CesiumGeospatial::Ellipsoid const&)

I believe the method exists in the library because I see this in nm -C libCesium3DTilesSelection.a output:

0000000000000000 T Cesium3DTilesSelection::ViewState::create(glm::vec<3ul, double, (glm::qualifier)0> const&, glm::vec<3ul, double, (glm::qualifier)0> const&, glm::vec<3ul, double, (glm::qualifier)0> const&, glm::vec<2ul, double, (glm::qualifier)0> const&, double, double, CesiumGeospatial::Ellipsoid const&)

Cesium-native version: 0.40.1 (we’d prefer to not bump higher due to c++20 requirement)
Android NDK: 25.1.8937393

Can anyone provide some guidance on why this might be happening?

Some more info. It’s not specifically static methods. If I do this:

CesiumGeospatial::Ellipsoid::WGS84.cartesianToCartographic(glm::dvec3(positionx, positiony, positionz));

I get this:

ld: error: undefined symbol: CesiumGeospatial::Ellipsoid::cartesianToCartographic(glm::vec<3, double, (glm::qualifier)0> const&) const
>>> did you mean: CesiumGeospatial::Ellipsoid::cartesianToCartographic(glm::vec<3ul, double, (glm::qualifier)0> const&) const
>>> defined in: C:/Users/user/.conan/data/cesium-native/0.40.1/_/_/package/2d2a093c27fdbf3a69a4d2cfecc25189242e71fc/android-arm64-v8a/lib/libCesiumGeospatial.a(Ellipsoid.cpp.o)

It’s starting to look like it’s a glm issue.

And it appears it’s only a problem in CesiumGeospatial, because if I try to use a function that takes a glm::dvec3 in CesiumGeometry it works fine.

auto pos = glm::dvec3(positionx, positiony, positionz);
CesiumGeometry::AxisAlignedBox box(0,0,0,100,100,100);
box.contains(pos);

I was able to resolve this issue. I found this related issue that led me to the CESIUM_GLM_STRICT_ENABLED cmake option. That sets three GLM compiler definitions: GLM_FORCE_XYZW_ONLY, GLM_FORCE_EXPLICIT_CTOR, and GLM_FORCE_SIZE_T_LENGTH. When I set those defines in my client application, linking works correctly.

Hi @kurtzmarc, welcome to the community!

Sorry that this post slipped through the cracks! We had some glm-related changes in Cesium Native that we noted in our changelog for v0.44.0:

  • Using Cesium Native in non-cmake projects now requires manually defining GLM_ENABLE_EXPERIMENTAL.
  • cesium-native no longer uses the GLM_FORCE_SIZE_T_LENGTH option with the glm library

The errors you were getting with glm seem related to these entries. I’m glad you were able to figure it out, though!