diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c90aeb4..f092c85 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -208,6 +208,9 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.9 + - name: Setup MSVC environment + uses: ilammy/msvc-dev-cmd@v1 + if: startsWith(matrix.platform, 'windows-') - name: Configure run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release - name: Build diff --git a/CMakeLists.txt b/CMakeLists.txt index 38dfbfe..b4d3482 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ target_sources(nod_ffi INTERFACE # Create a namespace alias for the library target. add_library(nod::nod ALIAS nod_ffi) -# ── Install ── +# Install include(GNUInstallDirs) if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(_NOD_INSTALL_DEFAULT ON) @@ -153,15 +153,39 @@ option(NOD_ENABLE_INSTALL "Generate install targets" ${_NOD_INSTALL_DEFAULT}) if (NOD_ENABLE_INSTALL) # Corrosion's install doesn't generate proper IMPORTED targets for consumers, # so we install the library files directly and generate our own CMake config. - # Rename from nod_ffi to nod. - install(FILES "$" - DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RENAME "$,${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}>" - ) + + # Shared library + if (WIN32) + # DLL to bin/ + install(FILES "$" + DESTINATION "${CMAKE_INSTALL_BINDIR}" + RENAME "${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}" + ) + # Import library to lib/ + install(FILES "$" + DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RENAME "${CMAKE_IMPORT_LIBRARY_PREFIX}nod${CMAKE_IMPORT_LIBRARY_SUFFIX}" + ) + else() + install(FILES "$" + DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RENAME "${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}" + ) + endif() + + # Static library + if (MSVC) + # On MSVC, use nod_static to avoid collision with the DLL import library + set(_nod_static_name "nod_static${CMAKE_STATIC_LIBRARY_SUFFIX}") + else() + set(_nod_static_name "${CMAKE_STATIC_LIBRARY_PREFIX}nod${CMAKE_STATIC_LIBRARY_SUFFIX}") + endif() install(FILES "$" DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RENAME "$,${CMAKE_STATIC_LIBRARY_PREFIX}nod${CMAKE_STATIC_LIBRARY_SUFFIX}>" + RENAME "${_nod_static_name}" ) + + # Header install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/nod-ffi/include/nod.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) diff --git a/cmake/nodConfig.cmake.in b/cmake/nodConfig.cmake.in index 462097d..4767d98 100644 --- a/cmake/nodConfig.cmake.in +++ b/cmake/nodConfig.cmake.in @@ -1,52 +1,76 @@ @PACKAGE_INIT@ -if (NOT TARGET nod::nod) - # Find the installed library - find_library(_nod_shared_lib - NAMES nod - PATHS "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@" - NO_DEFAULT_PATH - ) - find_library(_nod_static_lib - NAMES nod - PATHS "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@" - NO_DEFAULT_PATH - ) +set(_nod_libdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@") +set(_nod_incdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@") - if (_nod_shared_lib) - add_library(nod::nod SHARED IMPORTED) - set_target_properties(nod::nod PROPERTIES - IMPORTED_LOCATION "${_nod_shared_lib}" - INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@" - ) - # On Windows, set IMPORTED_IMPLIB for the import library - if (WIN32) - find_file(_nod_implib - NAMES nod.lib nod.dll.a - PATHS "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@" - NO_DEFAULT_PATH +if (NOT TARGET nod::nod_shared AND NOT TARGET nod::nod_static) + # Shared library + if (WIN32) + set(_nod_dll "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_BINDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}") + set(_nod_implib "${_nod_libdir}/${CMAKE_IMPORT_LIBRARY_PREFIX}nod${CMAKE_IMPORT_LIBRARY_SUFFIX}") + if (EXISTS "${_nod_dll}") + add_library(nod::nod_shared SHARED IMPORTED) + set_target_properties(nod::nod_shared PROPERTIES + IMPORTED_LOCATION "${_nod_dll}" + INTERFACE_INCLUDE_DIRECTORIES "${_nod_incdir}" ) - if (_nod_implib) - set_target_properties(nod::nod PROPERTIES IMPORTED_IMPLIB "${_nod_implib}") - endif () - unset(_nod_implib CACHE) - endif () - elseif (_nod_static_lib) - add_library(nod::nod STATIC IMPORTED) - set_target_properties(nod::nod PROPERTIES - IMPORTED_LOCATION "${_nod_static_lib}" - INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@" + if (EXISTS "${_nod_implib}") + set_target_properties(nod::nod_shared PROPERTIES + IMPORTED_IMPLIB "${_nod_implib}" + ) + endif() + endif() + else() + set(_nod_shared "${_nod_libdir}/${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}") + if (EXISTS "${_nod_shared}") + add_library(nod::nod_shared SHARED IMPORTED) + set_target_properties(nod::nod_shared PROPERTIES + IMPORTED_LOCATION "${_nod_shared}" + INTERFACE_INCLUDE_DIRECTORIES "${_nod_incdir}" + ) + endif() + endif() + + # Static library + if (MSVC) + set(_nod_static "${_nod_libdir}/nod_static${CMAKE_STATIC_LIBRARY_SUFFIX}") + else() + set(_nod_static "${_nod_libdir}/${CMAKE_STATIC_LIBRARY_PREFIX}nod${CMAKE_STATIC_LIBRARY_SUFFIX}") + endif() + if (EXISTS "${_nod_static}") + add_library(nod::nod_static STATIC IMPORTED) + set_target_properties(nod::nod_static PROPERTIES + IMPORTED_LOCATION "${_nod_static}" + INTERFACE_INCLUDE_DIRECTORIES "${_nod_incdir}" ) - else () + endif() + + # Default nod::nod target (respects BUILD_SHARED_LIBS) + if (BUILD_SHARED_LIBS AND TARGET nod::nod_shared) + add_library(nod::nod INTERFACE IMPORTED) + set_target_properties(nod::nod PROPERTIES + INTERFACE_LINK_LIBRARIES nod::nod_shared + ) + elseif (TARGET nod::nod_static) + add_library(nod::nod INTERFACE IMPORTED) + set_target_properties(nod::nod PROPERTIES + INTERFACE_LINK_LIBRARIES nod::nod_static + ) + elseif (TARGET nod::nod_shared) + add_library(nod::nod INTERFACE IMPORTED) + set_target_properties(nod::nod PROPERTIES + INTERFACE_LINK_LIBRARIES nod::nod_shared + ) + else() set(nod_FOUND FALSE) if (nod_FIND_REQUIRED) - message(FATAL_ERROR "nod library not found in ${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@") - endif () + message(FATAL_ERROR "nod library not found in ${_nod_libdir}") + endif() return() - endif () + endif() +endif() - unset(_nod_shared_lib CACHE) - unset(_nod_static_lib CACHE) -endif () +unset(_nod_libdir) +unset(_nod_incdir) check_required_components(nod)