# Building a shared library that depends on a shared library produced by GraalVM's native-image

**URL:** <https://discourse.cmake.org/t/building-a-shared-library-that-depends-on-a-shared-library-produced-by-graalvms-native-image/12879>\
**Category:** Code\
**Created:** [November 1, 2024, 2:59pm UTC](https://discourse.cmake.org/t/building-a-shared-library-that-depends-on-a-shared-library-produced-by-graalvms-native-image/12879 "2024-11-01T14:59:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattp](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mattp/32/5078_2.png) [@mattp](https://discourse.cmake.org/u/mattp)\
**Post date:** [November 1, 2024, 2:59pm UTC](https://discourse.cmake.org/t/building-a-shared-library-that-depends-on-a-shared-library-produced-by-graalvms-native-image/12879/1 "2024-11-01T14:59:11Z")

</div>

I’m working on a project where we have a C++ shared library which is (effectively) an API wrapper around our Java library, which is compiled down to C using GraalVM’s `native-image` tool.

The library is cross-platform, targeting Linux, macOS and Windows. Our existing build system gets GraalVM to build the shared library object plus header files. I then need to include that when I build the C++ source of the wrapping shared library.

We haven’t been using CMake, and I want to move away from our scratch build scripts to something more maintainable.

It’s not obvious to me how to include the Graal-generated library.

My initial approach was to use this in my `CMakeLists.txt` (targeting 3.27):

```auto
set(LIBSAXON_SO "libname-1.2.3.so")
if(APPLE)
    set(LIBSAXON_SO "libname-1.2.3.dylib")
endif()
add_library(libname SHARED IMPORTED)
set_property(TARGET libname PROPERTY
        IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/path_to/graalvm-generated-lib/${LIBNAME_SO}")
target_sources(libname INTERFACE
        FILE_SET HEADERS
        BASE_DIRS path_to/graalvm-generated-lib
        FILES path_to/graalvm-generated-lib/graal_isolate.h
        path_to/graalvm-generated-lib/graal_isolate_dynamic.h
        path_to/graalvm-generated-lib/libname-1.2.3.h
        path_to/graalvm-generated-lib/libname-1.2.3_dynamic.h

```

I’m not especially fond of this. There’s an awful lot of hard-coded versions and platform-specific conditionals in there (and it doesn’t even deal with Windows). Is there a pattern for handling this kind of thing (probably akin to using a commercially-supplied pre-compiled library) that I’ve missed and people would recommend?

Thanks, Matt

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [November 1, 2024, 3:32pm UTC](https://discourse.cmake.org/t/building-a-shared-library-that-depends-on-a-shared-library-produced-by-graalvms-native-image/12879/2 "2024-11-01T15:32:17Z")

</div>

Instead of a conditional platform-specific variable for the library binary file name you could use the [find\_library()](https://cmake.org/cmake/help/latest/command/find_library.html) function. That should take care of assigning appropriate prefixes/suffixes/extensions to the base library name.

Then instead of manually composing the list of public headers you could use a [GLOB](https://cmake.org/cmake/help/latest/command/file.html#glob), which is usually not very much recommended, but here it would be justified, I think.

Finally, in general, for finding a library that doesn’t have a CMake config, you could write your own custom [Find\*](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Finding%20Packages.html) module, perhaps using [this one](https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/FindZLIB.cmake) as (_a bit convoluted_) example. Having this module, your consuming projects will only need to do this:

```cmake
#list(APPEND CMAKE_MODULE_PATH "/path/to/your/cmake/modules")
find_package(SAXON REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${SAXON_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE SAXON::SAXON)

```

---

<div class="post-metadata">

**Author:** ![mattp](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mattp/32/5078_2.png) [@mattp](https://discourse.cmake.org/u/mattp)\
**Post date:** [November 5, 2024, 3:35pm UTC](https://discourse.cmake.org/t/building-a-shared-library-that-depends-on-a-shared-library-produced-by-graalvms-native-image/12879/3 "2024-11-05T15:35:51Z")

</div>

`find_library()` was a great idea, thank you. Looking at that, along with `find_path()` to get the path to the headers so I could use that variable in `target_include_directories()` has made things much simpler.

I realised that the library file naming was non-standard, and changing that also helped with keeping things straightforward.

Thanks again!
