I've edited the CMakeFileLists.txt (and project structure) of CNPY library to automatically generate a cnpy-config.cmake file for importing into my project.
Everything works fine: the library is compiled and .lib, .dll, .cmake files are correctly generated and installed (I've used Debug and Release configurations).
In particular, three configuration files are produced in cmake folder: cnpy-config.cmake, cnpy-config-debug.cmake, cnpy-config-release.cmake`
CMAKE_MINIMUM_REQUIRED(VERSION 3.25 FATAL_ERROR)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
project(CNPY VERSION 1.0.0)
if(NOT CMAKE_DEBUG_POSTFIX)
set(CMAKE_DEBUG_POSTFIX d)
endif()
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# option(ENABLE_STATIC "Build static (.a) library" OFF)
find_package(ZLIB REQUIRED)
add_library(cnpy SHARED)
target_sources(cnpy PRIVATE src/cnpy.cpp)
target_link_libraries(cnpy ZLIB::ZLIB)
target_include_directories(cnpy PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_compile_features(cnpy PUBLIC cxx_std_17)
install(
TARGETS cnpy
EXPORT cnpy_export
INCLUDES DESTINATION include
)
# Install directories
install (
DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION include
)
# Export configuration file
install(EXPORT cnpy_export
FILE cnpy-config.cmake
NAMESPACE cnpy::
# This is always relative to ${CMAKE_PREFIX_INSTALL}
DESTINATION cmake
)
Now I have my project (very basic right now) that uses cnpy:
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(MyProject)
message("Current configuration: ${CMAKE_BUILD_TYPE}")
find_package(ZLIB REQUIRED)
find_package(CNPY REQUIRED)
add_executable(MyExe)
target_sources(MyExe PRIVATE main.cpp)
target_link_libraries(MyExe PRIVATE cnpy::cnpy)
main.cpp
#include<cnpy.h>
#include<stdio.h>
#include<string>
int main()
{
std::string filename("C:\\some\\path\\array.npy");
#ifdef NDEBUG
printf("I'm in Release mode\n");
#else
printf("I'm in Debug mode\n");
#endif
auto arr = cnpy::npy_load(filename);
std::cout << "Read array of " << arr.as_vec<float>().size() << std::endl;
}
Everything works fine. BUT: main.exe requires both cnpy.dll and cnpyd.dll, no matter whether I'm building in Release or Debug mode.
Digging into cnpy-config.cmake, I noticed the following part of code, that includes ALWAYS both *-debug.cmake and *-release.cmake files.
[...]
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/cnpy-config-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
[...]
The content of the two files follow for clarity:
# cnpy-config-release.cmake
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "cnpy::cnpy" for configuration "Release"
set_property(TARGET cnpy::cnpy APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(cnpy::cnpy PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/cnpy.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/cnpy.dll"
)
list(APPEND _cmake_import_check_targets cnpy::cnpy )
list(APPEND _cmake_import_check_files_for_cnpy::cnpy "${_IMPORT_PREFIX}/lib/cnpy.lib" "${_IMPORT_PREFIX}/bin/cnpy.dll" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
# cnpy-config-debug.cmake
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Debug".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "cnpy::cnpy" for configuration "Debug"
set_property(TARGET cnpy::cnpy APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(cnpy::cnpy PROPERTIES
IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/cnpyd.lib"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/cnpyd.dll"
)
list(APPEND _cmake_import_check_targets cnpy::cnpy )
list(APPEND _cmake_import_check_files_for_cnpy::cnpy "${_IMPORT_PREFIX}/lib/cnpyd.lib" "${_IMPORT_PREFIX}/bin/cnpyd.dll" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
As far as I understand (I'm not a CMake expert TBH), the two debug and release versions of the library are always included.
Apart from a hack solution of manually editing the master configuration file to check upon configuration, such reported below (I don't like this solution), is there any solution to automatically generate a configuration file that can discern configurations, or help the as is (already generated) configuration file to discern the configuration?
IF (${CMAKE_BUILD_TYPE} MATCHES Debug)
include("${CMAKE_CURRENT_LIST_DIR}/cnpy-config-debug.cmake")
ELSE()
include(${CMAKE_CURRENT_LIST_DIR}/cnpy-config-release.cmake")
ENDIF()
Please, I've googled a lot of answers (inside and outside SO), but I've not got anything for this case in particular: If I was missing something and this is a duplicate, I'm really sorry.