From e77acdb7288ed39cbd4510e3b49bfb2ff45b709c Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Sat, 15 Jun 2024 01:07:22 +0000 Subject: [PATCH 01/25] Move build of external dependencies to CMAKE as external projects --- CMakeLists.txt | 80 ++++++++++++++++++++++++++++++++++++++++---------- Makefile | 74 +--------------------------------------------- 2 files changed, 65 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af463d4b..3db1bd0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,6 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # Enable setting version in the project statement if (POLICY CMP0048) cmake_policy(SET CMP0048 NEW) @@ -50,6 +49,59 @@ if (SR_FORTRAN) enable_language(Fortran) endif() +# Include external libraries +include(ExternalProject) +# Add hiredis as an external project +ExternalProject_Add(hiredis + GIT_REPOSITORY https://github.com/redis/hiredis.git + GIT_TAG v1.2.0 + CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + INSTALL_COMMAND make install +) + +# Define hiredis as an external project +ExternalProject_Get_Property(hiredis source_dir binary_dir) + +add_library(libhiredis UNKNOWN IMPORTED) +add_dependencies(libhiredis hiredis) + +# Set hiredis properties +set_target_properties(libhiredis PROPERTIES + IMPORTED_LOCATION ${binary_dir}/libhiredis.a + INTERFACE_INCLUDE_DIRECTORIES ${source_dir} +) + +# Define redis++ as an external project +ExternalProject_Add(redis++ + GIT_REPOSITORY https://github.com/sewenew/redis-plus-plus.git + GIT_TAG 1.3.10 + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/redis++ + INSTALL_COMMAND make install PREFIX=${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS -DREDIS_PLUS_PLUS_BUILD_TEST=OFF + -DREDIS_PLUS_PLUS_BUILD_SHARED=OFF + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + DEPENDS hiredis # Add hiredis as a dependency +) + +ExternalProject_Get_Property(redis++ source_dir binary_dir) + +add_library(libredis++ UNKNOWN IMPORTED) +add_dependencies(libredis++ redis++) + +set_target_properties(libredis++ PROPERTIES + IMPORTED_LOCATION ${binary_dir}/libredis++.a + INTERFACE_INCLUDE_DIRECTORIES ${source_dir} +) + +# Add pybind11 +include(FetchContent) +FetchContent_Declare( + pybind11 + GIT_REPOSITORY https://github.com/pybind/pybind11 + GIT_TAG v2.11.1 +) + + # For now, we only support Pedantic on the main library build. # If/when we fine-tune the examples and test cases, move this block # to smartredis_defs.cmake @@ -76,17 +128,7 @@ if (SR_PEDANTIC) endif() endif() -# Bring in third-party libaries needed for the SmartRedis library -find_library(REDISPP redis++ - PATHS ${CMAKE_SOURCE_DIR}/install/lib NO_DEFAULT_PATH - REQUIRED STATIC -) -find_library(HIREDIS hiredis - PATHS ${CMAKE_SOURCE_DIR}/install/lib NO_DEFAULT_PATH - REQUIRED STATIC -) find_package(Threads REQUIRED) -set(EXT_CLIENT_LIBRARIES ${REDISPP} ${HIREDIS}) # Define source code that goes into the SmartRedis library set(CLIENT_SRC @@ -142,13 +184,15 @@ if (STATIC_BUILD) set(TEMP_LIB_FULLNAME lib${TEMP_LIB_NAME}.a) set(SR_LIB_INSTALL_PATH ${CMAKE_SOURCE_DIR}/include/lib) add_library(smartredis ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) + add_dependencies(smartredis libhiredis libredis++) set_target_properties(smartredis PROPERTIES SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} ) set_target_properties(smartredis PROPERTIES OUTPUT_NAME ${TEMP_LIB_NAME} ) - target_link_libraries(smartredis PUBLIC ${EXT_CLIENT_LIBRARIES} PRIVATE Threads::Threads) + # target_link_libraries(smartredis PUBLIC ${EXT_CLIENT_LIBRARIES} PRIVATE Threads::Threads) + target_link_libraries(smartredis PRIVATE Threads::Threads) # Merge SmartRedis static library with dependencies # . Create a sacrificial dummy file so we have source to make a target against @@ -170,10 +214,11 @@ if (STATIC_BUILD) ) # Install static library - install(TARGETS ${SMARTREDIS_LIB} + install( TARGETS ${SMARTREDIS_LIB} LIBRARY DESTINATION lib) else () # Shared library build add_library(smartredis ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) + add_dependencies(smartredis libhiredis libredis++) set_target_properties(smartredis PROPERTIES SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} ) @@ -210,6 +255,7 @@ if (SR_FORTRAN) set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/include") # Fortran library add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} ${FORTRAN_SRC}) + add_dependencies(smartredis-fortran smartredis) set_target_properties(smartredis-fortran PROPERTIES SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} ) @@ -225,9 +271,11 @@ endif() # Build the Python library for SmartRedis if(SR_PYTHON) message("-- Python client build enabled") - add_subdirectory(${CMAKE_SOURCE_DIR}/third-party/pybind - ${CMAKE_SOURCE_DIR}/third-party/pybind/build) - + FetchContent_GetProperties(pybind11) + if(NOT pybind11_POPULATED) + FetchContent_Populate(pybind11) + endif() + add_subdirectory(${pybind11_SOURCE_DIR} ${pybind11_BINARY_DIR}) pybind11_add_module(smartredisPy src/python/src/pyclient.cpp src/python/src/pyconfigoptions.cpp diff --git a/Makefile b/Makefile index 6d28bda4..4f1c8728 100644 --- a/Makefile +++ b/Makefile @@ -29,24 +29,6 @@ MAKEFLAGS += --no-print-directory SHELL:=/bin/bash CWD := $(shell pwd) -# Params for third-party software -HIREDIS_URL := https://github.com/redis/hiredis.git -HIREDIS_VER := v1.2.0 -RPP_URL := https://github.com/sewenew/redis-plus-plus.git -RPP_VER := 1.3.10 -PYBIND_URL := https://github.com/pybind/pybind11.git -PYBIND_VER := v2.11.1 -REDIS_URL := https://github.com/redis/redis.git -REDIS_VER := 7.2.4 -REDISAI_URL := https://github.com/RedisAI/RedisAI.git -# REDISAI_VER is controlled instead by SR_TEST_REDISAI_VER below -CATCH2_URL := https://github.com/catchorg/Catch2.git -CATCH2_VER := v2.13.6 -LCOV_URL := https://github.com/linux-test-project/lcov.git -LCOV_VER := v2.0 -DEP_CC := gcc -DEP_CXX := g++ - # Build variables NPROC := $(shell nproc 2>/dev/null || python -c "import multiprocessing as mp; print (mp.cpu_count())" 2>/dev/null || echo 4) SR_BUILD := Release @@ -114,16 +96,9 @@ help: # help: Build targets # help: ------------- -# help: deps - Make SmartRedis dependencies -.PHONY: deps -deps: hiredis -deps: redis-plus-plus -deps: pybind -deps: - # help: lib - Build SmartRedis C/C++/Python clients into a dynamic library .PHONY: lib -lib: deps +lib: lib: @cmake -S . -B build/$(SR_BUILD) -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ -DSR_PEDANTIC=$(SR_PEDANTIC) -DSR_FORTRAN=$(SR_FORTRAN) -DSR_PYTHON=$(SR_PYTHON) @@ -493,53 +468,6 @@ test-examples: ############################################################################ # hidden build targets for third-party software -# Hiredis (hidden build target) -.PHONY: hiredis -hiredis: install/lib/libhiredis.a - -third-party/hiredis: - @mkdir -p third-party - @cd third-party && \ - git clone $(HIREDIS_URL) hiredis --branch $(HIREDIS_VER) --depth=1 - -install/lib/libhiredis.a: third-party/hiredis - @cd third-party/hiredis && \ - make LIBRARY_PATH=lib CC=$(DEP_CC) CXX=$(DEP_CXX) PREFIX="../../install" install -j $(NPROC) && \ - rm -f ../../install/lib/libhiredis*.so* && \ - rm -f ../../install/lib/libhiredis*.dylib* && \ - echo "Finished installing Hiredis" - -# Redis-plus-plus (hidden build target) -.PHONY: redis-plus-plus -redis-plus-plus: install/lib/libredis++.a - -third-party/redis-plus-plus: - @mkdir -p third-party - @cd third-party && \ - git clone $(RPP_URL) redis-plus-plus --branch $(RPP_VER) --depth=1 - -install/lib/libredis++.a: third-party/redis-plus-plus - @cd third-party/redis-plus-plus && \ - mkdir -p compile && \ - cd compile && \ - cmake -DCMAKE_BUILD_TYPE=Release -DREDIS_PLUS_PLUS_BUILD_TEST=OFF \ - -DREDIS_PLUS_PLUS_BUILD_SHARED=OFF -DCMAKE_PREFIX_PATH="../../../install/lib/" \ - -DCMAKE_INSTALL_PREFIX="../../../install" -DCMAKE_CXX_STANDARD=17 \ - -DCMAKE_INSTALL_LIBDIR="lib" -DCMAKE_C_COMPILER=$(DEP_CC) -DCMAKE_CXX_COMPILER=$(DEP_CXX) .. && \ - make CC=$(DEP_CC) CXX=$(RPP_CX) -j $(NPROC) && \ - make CC=$(DEP_CC) CXX=$(RPP_CX) install && \ - echo "Finished installing Redis-plus-plus" - -# Pybind11 (hidden build target) -.PHONY: pybind -pybind: third-party/pybind/include/pybind11/pybind11.h -third-party/pybind/include/pybind11/pybind11.h: - @mkdir -p third-party - @cd third-party && \ - git clone $(PYBIND_URL) pybind --branch $(PYBIND_VER) --depth=1 - @mkdir -p third-party/pybind/build && \ - echo "Finished installing Pybind11" - # Redis (hidden test target) .PHONY: redis From a11b64f9915c442120e60c4e0ae10d1a244469a5 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Mon, 17 Jun 2024 21:46:25 +0000 Subject: [PATCH 02/25] Remove make dep stage from setup.py --- setup.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/setup.py b/setup.py index 7f9388e8..428b9d4c 100644 --- a/setup.py +++ b/setup.py @@ -73,14 +73,6 @@ def run(self): env.get('CXXFLAGS', ''), self.distribution.get_version()) - # Build dependencies - print('-'*10, 'Building third-party dependencies', '-'*40) - subprocess.check_call( - [self.make, "deps"], - cwd=source_directory, - shell=False - ) - # Run CMake config step print('-'*10, 'Configuring build', '-'*40) config_args = [ From 1d6ea7f5e1a8c2d73b5a8172612a990fbc60079b Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Mon, 17 Jun 2024 23:33:22 +0000 Subject: [PATCH 03/25] Update changelog --- doc/changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/changelog.md b/doc/changelog.md index 2e51bb3d..3575a101 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -7,6 +7,7 @@ Released on 14 May 2024 Description - Remove broken oss.redis.com URLs from documentation +- Streamline compilation of SmartRedis dependencies - Pin NumPy version to 1.x - Improve client error logging - Fix pylint regression error @@ -32,6 +33,12 @@ Description Detailed Notes +- hiredis, redis++, and pybind are now retrieved and installed + in `CMakeLists.txt` instead of in the Makefile. This decouples the + user-facing side of SmartRedis from the Makefile, which now can be + used as a convenient interface to compile SmartRedis with various + options and coordinate testing + ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) - The new major version release of Numpy is incompatible with modules compiled against Numpy 1.x. For both SmartSim and SmartRedis we request a 1.x version of numpy. This is needed in SmartSim because some of the downstream From 7f0a5e45910432267832ade03fbb71ee9a5b12ce Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Mon, 17 Jun 2024 23:38:41 +0000 Subject: [PATCH 04/25] Fix build for Docker images --- CMakeLists.txt | 10 ++++------ images/Dockerfile | 5 +++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3db1bd0c..7e2b646e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,7 +101,6 @@ FetchContent_Declare( GIT_TAG v2.11.1 ) - # For now, we only support Pedantic on the main library build. # If/when we fine-tune the examples and test cases, move this block # to smartredis_defs.cmake @@ -191,7 +190,6 @@ if (STATIC_BUILD) set_target_properties(smartredis PROPERTIES OUTPUT_NAME ${TEMP_LIB_NAME} ) - # target_link_libraries(smartredis PUBLIC ${EXT_CLIENT_LIBRARIES} PRIVATE Threads::Threads) target_link_libraries(smartredis PRIVATE Threads::Threads) # Merge SmartRedis static library with dependencies @@ -214,7 +212,7 @@ if (STATIC_BUILD) ) # Install static library - install( TARGETS ${SMARTREDIS_LIB} + install(TARGETS ${SMARTREDIS_LIB} LIBRARY DESTINATION lib) else () # Shared library build add_library(smartredis ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) @@ -225,7 +223,7 @@ else () # Shared library build set_target_properties(smartredis PROPERTIES OUTPUT_NAME ${SMARTREDIS_LIB} ) - target_link_libraries(smartredis PUBLIC ${EXT_CLIENT_LIBRARIES} PRIVATE Threads::Threads) + target_link_libraries(smartredis PRIVATE Threads::Threads) # Install dynamic library install(TARGETS smartredis @@ -262,7 +260,7 @@ if (SR_FORTRAN) set_target_properties(smartredis-fortran PROPERTIES OUTPUT_NAME ${SMARTREDIS_FORTRAN_LIB} ) - target_link_libraries(smartredis-fortran PUBLIC smartredis ${EXT_CLIENT_LIBRARIES}) + target_link_libraries(smartredis-fortran PUBLIC smartredis) # Install dynamic library and headers install(TARGETS smartredis-fortran LIBRARY DESTINATION lib) @@ -285,7 +283,7 @@ if(SR_PYTHON) ${CLIENT_SRC} src/python/bindings/bind.cpp) - target_link_libraries(smartredisPy PUBLIC ${EXT_CLIENT_LIBRARIES}) + add_dependencies(smartredisPy libhiredis libredis++) install(TARGETS smartredisPy LIBRARY DESTINATION lib) install(TARGETS smartredisPy LIBRARY DESTINATION ../src/python/module/smartredis) else() diff --git a/images/Dockerfile b/images/Dockerfile index a69b50cf..4d44fc61 100644 --- a/images/Dockerfile +++ b/images/Dockerfile @@ -50,8 +50,9 @@ COPY . /usr/local/src/SmartRedis # Compile and install WORKDIR /usr/local/src/SmartRedis RUN pip3 install --upgrade pip -RUN make clobber && make lib SR_FORTRAN=ON SR_PYTHON=ON && pip install . && rm -rf ~/.cache/pip \ - && rm -rf build tests examples images utils third-party doc images +RUN make clobber && make lib SR_FORTRAN=ON SR_PYTHON=ON +RUN pip install . && rm -rf ~/.cache/pip \ + && rm -rf build tests examples images utils third-party doc # Copy install files and directories to /usr/local/lib and # usr/local/include and delete unnecessary build files From f0b78a3a8c952cbe173a76a00a40a06b717922ef Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 18 Jun 2024 00:23:35 +0000 Subject: [PATCH 05/25] Fixed visibility of libhiredis and redis++ --- CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e2b646e..b0e38f50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,10 @@ include(ExternalProject) ExternalProject_Add(hiredis GIT_REPOSITORY https://github.com/redis/hiredis.git GIT_TAG v1.2.0 - CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true INSTALL_COMMAND make install ) @@ -79,6 +82,7 @@ ExternalProject_Add(redis++ INSTALL_COMMAND make install PREFIX=${CMAKE_INSTALL_PREFIX} CMAKE_ARGS -DREDIS_PLUS_PLUS_BUILD_TEST=OFF -DREDIS_PLUS_PLUS_BUILD_SHARED=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} DEPENDS hiredis # Add hiredis as a dependency ) @@ -105,6 +109,7 @@ FetchContent_Declare( # If/when we fine-tune the examples and test cases, move this block # to smartredis_defs.cmake # Note: -Wextra can be added after unused parameters are addressed + if (SR_PEDANTIC) if( (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR @@ -190,7 +195,7 @@ if (STATIC_BUILD) set_target_properties(smartredis PROPERTIES OUTPUT_NAME ${TEMP_LIB_NAME} ) - target_link_libraries(smartredis PRIVATE Threads::Threads) + target_link_libraries(smartredis PUBLIC libhiredis libredis++ PRIVATE Threads::Threads) # Merge SmartRedis static library with dependencies # . Create a sacrificial dummy file so we have source to make a target against @@ -223,7 +228,7 @@ else () # Shared library build set_target_properties(smartredis PROPERTIES OUTPUT_NAME ${SMARTREDIS_LIB} ) - target_link_libraries(smartredis PRIVATE Threads::Threads) + target_link_libraries(smartredis PUBLIC libhiredis libredis++ PRIVATE Threads::Threads) # Install dynamic library install(TARGETS smartredis From 7ec7a570dd9452d0b7e630a8c1e174184222a7cd Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 18 Jun 2024 00:23:51 +0000 Subject: [PATCH 06/25] Restore accidental deletion of test dependencies --- Makefile | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 4f1c8728..ab24dcb1 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,18 @@ SR_PEDANTIC := OFF SR_FORTRAN := OFF SR_PYTHON := OFF +# Test dependencies +REDIS_URL := https://github.com/redis/redis.git +REDIS_VER := 7.2.4 +REDISAI_URL := https://github.com/RedisAI/RedisAI.git +CATCH2_URL := https://github.com/catchorg/Catch2.git +CATCH2_VER := v2.13.6 +LCOV_URL := https://github.com/linux-test-project/lcov.git +LCOV_VER := v2.0 + # Test variables +DEP_CC := gcc +DEP_CXX := g++ COV_FLAGS := SR_TEST_REDIS_MODE := Clustered SR_TEST_UDS_FILE := /tmp/redis.sock @@ -468,20 +479,6 @@ test-examples: ############################################################################ # hidden build targets for third-party software -# Redis (hidden test target) -.PHONY: redis - -third-party/redis: - @mkdir -p third-party - @cd third-party && \ - git clone $(REDIS_URL) redis --branch $(REDIS_VER) --depth=1 - -redis: third-party/redis/src/redis-server -third-party/redis/src/redis-server: third-party/redis - @cd third-party/redis && \ - make CC=$(DEP_CC) CXX=$(DEP_CXX) MALLOC=libc -j $(NPROC) && \ - echo "Finished installing redis" - # cudann-check (hidden test target) # checks cuda dependencies for GPU build .PHONY: cudann-check @@ -504,6 +501,19 @@ ifeq (,$(wildcard $(CUDNN_LIBRARY)/libcudnn.so)) endif endif +# Redis (hidden test target) +.PHONY: redis +third-party/redis: + @mkdir -p third-party + @cd third-party && \ + git clone $(REDIS_URL) redis --branch $(REDIS_VER) --depth=1 + +redis: third-party/redis/src/redis-server +third-party/redis/src/redis-server: third-party/redis + @cd third-party/redis && \ + make CC=$(DEP_CC) CXX=$(DEP_CXX) MALLOC=libc -j $(NPROC) && \ + echo "Finished installing redis" + # RedisAI (hidden test target) third-party/RedisAI: @mkdir -p third-party From aea6b39dc0fe449105721a492b75ee889ec64740 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 18 Jun 2024 17:28:41 +0000 Subject: [PATCH 07/25] Add linking of external libraries to python client --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0e38f50..08e83fe9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -287,8 +287,8 @@ if(SR_PYTHON) src/python/src/pysrobject.cpp ${CLIENT_SRC} src/python/bindings/bind.cpp) - add_dependencies(smartredisPy libhiredis libredis++) + target_link_libraries(smartredisPy PUBLIC libhiredis libredis++) install(TARGETS smartredisPy LIBRARY DESTINATION lib) install(TARGETS smartredisPy LIBRARY DESTINATION ../src/python/module/smartredis) else() From 7eaa44fd22e9f8d9538c916d4fa7b0100a4e1693 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 18 Jun 2024 22:34:14 +0000 Subject: [PATCH 08/25] Shallow clone of external dependencies --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08e83fe9..918ace22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ include(ExternalProject) ExternalProject_Add(hiredis GIT_REPOSITORY https://github.com/redis/hiredis.git GIT_TAG v1.2.0 + GIT_SHALLOW 1 CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} @@ -78,6 +79,7 @@ set_target_properties(libhiredis PROPERTIES ExternalProject_Add(redis++ GIT_REPOSITORY https://github.com/sewenew/redis-plus-plus.git GIT_TAG 1.3.10 + GIT_SHALLOW 1 PREFIX ${CMAKE_CURRENT_BINARY_DIR}/redis++ INSTALL_COMMAND make install PREFIX=${CMAKE_INSTALL_PREFIX} CMAKE_ARGS -DREDIS_PLUS_PLUS_BUILD_TEST=OFF From 9e6f51bbc341fecf0985b0042b58701c79fd5a81 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Thu, 20 Jun 2024 23:37:17 +0000 Subject: [PATCH 09/25] Create install configs and update CMakeLists --- CMakeLists.txt | 154 ++++++++++++++++------- Config.smartredis-fortran.cmake.in | 5 + Config.smartredis.cmake.in | 5 + Makefile | 34 +++-- examples/parallel/cpp/CMakeLists.txt | 37 +----- examples/parallel/fortran/CMakeLists.txt | 76 +---------- examples/serial/c/CMakeLists.txt | 48 +------ examples/serial/cpp/CMakeLists.txt | 36 +----- examples/serial/fortran/CMakeLists.txt | 75 +---------- images/Dockerfile | 8 +- tests/c/CMakeLists.txt | 52 +------- tests/cpp/CMakeLists.txt | 38 +----- tests/docker/c/CMakeLists.txt | 8 +- tests/docker/c/Dockerfile | 2 +- tests/docker/cpp/CMakeLists.txt | 10 +- tests/docker/cpp/Dockerfile | 2 +- tests/docker/fortran/CMakeLists.txt | 15 +-- tests/docker/fortran/Dockerfile | 2 +- tests/fortran/CMakeLists.txt | 88 ++----------- 19 files changed, 186 insertions(+), 509 deletions(-) create mode 100644 Config.smartredis-fortran.cmake.in create mode 100644 Config.smartredis.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 918ace22..15ccf7b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,16 +32,20 @@ endif (POLICY CMP0048) cmake_minimum_required(VERSION 3.13) project(SmartRedis VERSION "0.5.3") +include(GNUInstallDirs) + # Configure options for the SmartRedis project option(SR_PYTHON "Build the python module" OFF) option(SR_FORTRAN "Build the fortran client library" OFF) option(SR_PEDANTIC "Build with pickiest compiler settings" OFF) set(CMAKE_CXX_STANDARD 17) -set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) +endif() set(CMAKE_CXX_VISIBILITY_PRESET default) set(THREADS_PREFER_PTHREAD_FLAG ON) -set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}) include(smartredis_defs) # If we want to use Fortran, we have to tell CMake to use it @@ -65,38 +69,44 @@ ExternalProject_Add(hiredis # Define hiredis as an external project ExternalProject_Get_Property(hiredis source_dir binary_dir) +set(hiredis_source_dir ${source_dir}) +set(hiredis_binary_dir ${binary_dir}) add_library(libhiredis UNKNOWN IMPORTED) add_dependencies(libhiredis hiredis) # Set hiredis properties set_target_properties(libhiredis PROPERTIES - IMPORTED_LOCATION ${binary_dir}/libhiredis.a - INTERFACE_INCLUDE_DIRECTORIES ${source_dir} + IMPORTED_LOCATION ${hiredis_binary_dir}/libhiredis.a + INTERFACE_INCLUDE_DIRECTORIES ${hiredis_source_dir} ) +include(CMakePrintHelpers) +cmake_print_variables(hiredis_source_dir) # Define redis++ as an external project ExternalProject_Add(redis++ GIT_REPOSITORY https://github.com/sewenew/redis-plus-plus.git GIT_TAG 1.3.10 GIT_SHALLOW 1 - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/redis++ INSTALL_COMMAND make install PREFIX=${CMAKE_INSTALL_PREFIX} CMAKE_ARGS -DREDIS_PLUS_PLUS_BUILD_TEST=OFF - -DREDIS_PLUS_PLUS_BUILD_SHARED=OFF - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + -DREDIS_PLUS_PLUS_BUILD_SHARED=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} DEPENDS hiredis # Add hiredis as a dependency ) ExternalProject_Get_Property(redis++ source_dir binary_dir) +set(redis++_source_dir ${source_dir}) +set(redis++_binary_dir ${binary_dir}) +cmake_print_variables(redis++_source_dir) add_library(libredis++ UNKNOWN IMPORTED) add_dependencies(libredis++ redis++) set_target_properties(libredis++ PROPERTIES - IMPORTED_LOCATION ${binary_dir}/libredis++.a - INTERFACE_INCLUDE_DIRECTORIES ${source_dir} + IMPORTED_LOCATION ${redis++_binary_dir}/libredis++.a + INTERFACE_INCLUDE_DIRECTORIES ${redis++_source_dir} ) # Add pybind11 @@ -117,8 +127,8 @@ if (SR_PEDANTIC) (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC") ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -pedantic -Wextra") - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wall -Werror -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -pedantic -Wextra -Wno-unused-parameter -Wno-unused-variable") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wall -Werror -Wextra -Wno-unused-parameter -Wno-unused-variable") elseif( (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") OR (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") @@ -178,28 +188,23 @@ set(CLIENT_SRC src/cpp/utility.cpp ) -# Define include directories for header files -include_directories(SYSTEM - include - install/include -) - +include_directories(SYSTEM $) # Build the main SmartRedis library if (STATIC_BUILD) set(TEMP_LIB_NAME sr${SR_STATIC_NAME_SUFFIX}-static) set(TEMP_LIB_FULLNAME lib${TEMP_LIB_NAME}.a) set(SR_LIB_INSTALL_PATH ${CMAKE_SOURCE_DIR}/include/lib) - add_library(smartredis ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) - add_dependencies(smartredis libhiredis libredis++) - set_target_properties(smartredis PROPERTIES + add_library(${TEMP_LIB_NAME} ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) + add_dependencies(${TEMP_LIB_NAME} libhiredis libredis++) + set_target_properties(${TEMP_LIB_NAME} PROPERTIES SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} ) - set_target_properties(smartredis PROPERTIES + set_target_properties(${TEMP_LIB_NAME} PROPERTIES OUTPUT_NAME ${TEMP_LIB_NAME} ) - target_link_libraries(smartredis PUBLIC libhiredis libredis++ PRIVATE Threads::Threads) + target_link_libraries(${TEMP_LIB_NAME} PRIVATE libhiredis libredis++ Threads::Threads) - # Merge SmartRedis static library with dependencies + # Merge SmartRedis static library with dependenciee # . Create a sacrificial dummy file so we have source to make a target against set(DUMMY_FILE ${CMAKE_BINARY_DIR}/merge-dummy.cpp) file( @@ -211,37 +216,45 @@ if (STATIC_BUILD) # . Archive the static libraries together into a thin library add_custom_command( - TARGET smartredis + TARGET ${SMARTREDIS_LIB} POST_BUILD - COMMAND rm -f lib${SMARTREDIS_LIB}.a && mkdir -p ${SR_LIB_INSTALL_PATH} && cp ${CMAKE_BINARY_DIR}/${TEMP_LIB_FULLNAME} ${SR_LIB_INSTALL_PATH} && ar crT lib${SMARTREDIS_LIB}.a ${STATIC_LIB_COMPONENTS} + COMMAND rm -f lib${SMARTREDIS_LIB}.a && mkdir -p ${SR_LIB_INSTALL_PATH} && cp ${CMAKE_BINARY_DIR}/${TEMP_LIB_FULLNAME} ${SR_LIB_INSTALL_PATH} && ar crT lib${SMARTREDIS_LIB}.a ${STATIC_LIB_COMPONENTS} && rm ${CMAKE_INSTALL_PREFIX}/lib/{libhiredis.a,libredis++.a} VERBATIM - COMMENT "Bundling static libraries together as lib${SMARTREDIS_LIB}.a" + COMMENT "Creating lib${SMARTREDIS_LIB}.a and removing intermediate libraries" ) - # Install static library - install(TARGETS ${SMARTREDIS_LIB} - LIBRARY DESTINATION lib) else () # Shared library build - add_library(smartredis ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) - add_dependencies(smartredis libhiredis libredis++) - set_target_properties(smartredis PROPERTIES + add_library(${SMARTREDIS_LIB} ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) + add_dependencies(${SMARTREDIS_LIB} libhiredis libredis++) + set_target_properties(${SMARTREDIS_LIB} PROPERTIES SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} ) - set_target_properties(smartredis PROPERTIES + set_target_properties(${SMARTREDIS_LIB} PROPERTIES OUTPUT_NAME ${SMARTREDIS_LIB} ) - target_link_libraries(smartredis PUBLIC libhiredis libredis++ PRIVATE Threads::Threads) + target_include_directories(${SMARTREDIS_LIB} PUBLIC + $ + ) + target_link_libraries(smartredis PRIVATE libhiredis libredis++ Threads::Threads) + add_custom_command( + TARGET smartredis + POST_BUILD + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig ${CMAKE_INSTALL_PREFIX}/lib/cmake + VERBATIM + COMMENT "Removing intermediate static libraries" + ) - # Install dynamic library - install(TARGETS smartredis - LIBRARY DESTINATION lib) endif() +install( + TARGETS ${SMARTREDIS_LIB} + EXPORT smartredis-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) # Install SmartRedis header files -install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/" - DESTINATION "include" - FILES_MATCHING - PATTERN "*.h" PATTERN "*.tcc" PATTERN "*.inc" +install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) # Build the Fortran library @@ -270,7 +283,9 @@ if (SR_FORTRAN) target_link_libraries(smartredis-fortran PUBLIC smartredis) # Install dynamic library and headers install(TARGETS smartredis-fortran - LIBRARY DESTINATION lib) + EXPORT smartredis-fortran-targets + LIBRARY DESTINATION lib + ) endif() # Build the Python library for SmartRedis @@ -290,9 +305,58 @@ if(SR_PYTHON) ${CLIENT_SRC} src/python/bindings/bind.cpp) add_dependencies(smartredisPy libhiredis libredis++) - target_link_libraries(smartredisPy PUBLIC libhiredis libredis++) - install(TARGETS smartredisPy LIBRARY DESTINATION lib) + target_link_libraries(smartredisPy PRIVATE libhiredis libredis++) + target_include_directories(smartredisPy PUBLIC + $ + ) + install(TARGETS smartredisPy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS smartredisPy LIBRARY DESTINATION ../src/python/module/smartredis) else() message("-- Skipping Python client build") endif() + +install(EXPORT smartredis-targets + FILE smartredis.cmake + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis +) +include(CMakePackageConfigHelpers) +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.smartredis.cmake.in + smartredisConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis +) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/smartredisConfigVersion.cmake" + VERSION "${VERSION}" + COMPATIBILITY AnyNewerVersion +) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/smartredisConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/smartredisConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis + ) + +if(SR_FORTRAN) + install(EXPORT smartredis-fortran-targets + FILE smartredis-fortran.cmake + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran + ) + include(CMakePackageConfigHelpers) + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.smartredis-fortran.cmake.in + smartredis-fortranConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran + ) + + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfigVersion.cmake" + VERSION "${VERSION}" + COMPATIBILITY AnyNewerVersion + ) + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran + ) +endif() \ No newline at end of file diff --git a/Config.smartredis-fortran.cmake.in b/Config.smartredis-fortran.cmake.in new file mode 100644 index 00000000..d3ca02b4 --- /dev/null +++ b/Config.smartredis-fortran.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/smartredis-fortran.cmake") + +check_required_components(smartredis-fortran) diff --git a/Config.smartredis.cmake.in b/Config.smartredis.cmake.in new file mode 100644 index 00000000..28feae2c --- /dev/null +++ b/Config.smartredis.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/smartredis.cmake") + +check_required_components(smartredis) diff --git a/Makefile b/Makefile index ab24dcb1..50b889ad 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ SR_LINK := Shared SR_PEDANTIC := OFF SR_FORTRAN := OFF SR_PYTHON := OFF +SR_PREFIX := $(CWD)/install # Test dependencies REDIS_URL := https://github.com/redis/redis.git @@ -58,6 +59,7 @@ SR_TEST_REDISAI_VER := v1.2.7 SR_TEST_DEVICE := cpu SR_TEST_PYTEST_FLAGS := -vv -s + # Do not remove this block. It is used by the 'help' rule when # constructing the help output. # help: @@ -112,7 +114,8 @@ help: lib: lib: @cmake -S . -B build/$(SR_BUILD) -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ - -DSR_PEDANTIC=$(SR_PEDANTIC) -DSR_FORTRAN=$(SR_FORTRAN) -DSR_PYTHON=$(SR_PYTHON) + -DSR_PEDANTIC=$(SR_PEDANTIC) -DSR_FORTRAN=$(SR_FORTRAN) -DSR_PYTHON=$(SR_PYTHON) \ + -DCMAKE_INSTALL_PREFIX=$(SR_PREFIX) @cmake --build build/$(SR_BUILD) -- -j $(NPROC) @cmake --install build/$(SR_BUILD) @@ -148,7 +151,9 @@ test-deps-gpu: test-deps build-tests: test-deps build-tests: test-lib @cmake -S tests -B build/$(SR_BUILD)/tests/$(SR_LINK) \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK) -- -j $(NPROC) @@ -157,7 +162,8 @@ build-tests: test-lib build-test-cpp: test-deps build-test-cpp: test-lib @cmake -S tests/cpp -B build/$(SR_BUILD)/tests/$(SR_LINK)/cpp \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/cpp -- -j $(NPROC) # help: build-unit-test-cpp - build the C++ unit tests @@ -165,7 +171,8 @@ build-test-cpp: test-lib build-unit-test-cpp: test-deps build-unit-test-cpp: test-lib @cmake -S tests/cpp/unit-tests -B build/$(SR_BUILD)/tests/$(SR_LINK)/cpp/unit-tests \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/cpp/unit-tests -- -j $(NPROC) # help: build-test-c - build the C tests @@ -173,7 +180,8 @@ build-unit-test-cpp: test-lib build-test-c: test-deps build-test-c: test-lib @cmake -S tests/c -B build/$(SR_BUILD)/tests/$(SR_LINK)/c \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/c -- -j $(NPROC) @@ -183,7 +191,9 @@ build-test-fortran: test-deps build-test-fortran: SR_FORTRAN=ON build-test-fortran: test-lib @cmake -S tests/fortran -B build/$(SR_BUILD)/tests/$(SR_LINK)/fortran \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/fortran -- -j $(NPROC) @@ -191,7 +201,9 @@ build-test-fortran: test-lib .PHONY: build-examples build-examples: lib @cmake -S examples -B build/$(SR_BUILD)/examples/$(SR_LINK) -DSR_BUILD=$(SR_BUILD) \ - -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) + -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran @cmake --build build/$(SR_BUILD)/examples/$(SR_LINK) -- -j $(NPROC) @@ -199,7 +211,9 @@ build-examples: lib .PHONY: build-example-serial build-example-serial: lib @cmake -S examples/serial -B build/$(SR_BUILD)/examples/$(SR_LINK)/serial \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran @cmake --build build/$(SR_BUILD)/examples/$(SR_LINK)/serial @@ -207,7 +221,9 @@ build-example-serial: lib .PHONY: build-example-parallel build-example-parallel: lib @cmake -S examples/parallel -B build/$(SR_BUILD)/examples/$(SR_LINK)/parallel \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) + -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ + -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran @cmake --build build/$(SR_BUILD)/examples/$(SR_LINK)/parallel diff --git a/examples/parallel/cpp/CMakeLists.txt b/examples/parallel/cpp/CMakeLists.txt index d779181c..4a70fb0c 100644 --- a/examples/parallel/cpp/CMakeLists.txt +++ b/examples/parallel/cpp/CMakeLists.txt @@ -33,42 +33,9 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../..") -include(smartredis_defs) - -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../../install/") -endif() - # Locate dependencies find_package(MPI) -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) - -# Select libraries for build -if (STATIC_BUILD) - # Static builds have an extra dependency on the Pthreads library - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - ${SR_LIB} - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis library - set(SMARTREDIS_LIBRARIES ${SR_LIB}) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${MPI_INCLUDE_PATH} - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis) # Define all the examples to be built list(APPEND EXECUTABLES @@ -86,6 +53,6 @@ foreach(EXECUTABLE ${EXECUTABLES}) ) target_link_libraries(${EXECUTABLE}_cpp_parallel MPI::MPI_CXX - ${SMARTREDIS_LIBRARIES} + smartredis ) endforeach() diff --git a/examples/parallel/fortran/CMakeLists.txt b/examples/parallel/fortran/CMakeLists.txt index 27c4444f..9701247f 100644 --- a/examples/parallel/fortran/CMakeLists.txt +++ b/examples/parallel/fortran/CMakeLists.txt @@ -34,82 +34,12 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../..") -include(smartredis_defs) - -# Assume by default that users should link against the install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../../install/") -endif() - -# Locate dependencies -# . MPI find_package(MPI REQUIRED) IF(NOT MPI_Fortran_FOUND) message(FATAL_ERROR "Could not find Fortran MPI components") endif() -# . Main SmartRedis Library (C/C++ based) -add_library(smartredis-main ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} -) -# . SmartRedis Fortran Library (Fortran based) -add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_FTN_LIB ${SMARTREDIS_FORTRAN_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-fortran PROPERTIES - IMPORTED_LOCATION ${SR_FTN_LIB} -) - -# Select libraries for build -if (STATIC_BUILD) - # The CMake "preferred" approach only seems to work with the GNU - # compiler. We will streamline this in the future - if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - # Mark that SmartRedis requires the C++ linker - set_target_properties(smartredis-main PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - ) - set_target_properties(smartredis-fortran PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "FORTRAN" - ) - else() # Tested with PGI, Intel - # For other compilers, don't set languages so that CMake will use the Fortran linker (default) - - # Add the stdc++ linker flag - set(CMAKE_EXE_LINKER_FLAGS "-lstdc++ ${CMAKE_EXE_LINKER_FLAGS}") - endif() - - # Static builds have an extra dependency on the Pthreads library - # The order of libraries here is crucial to get dependencies covered - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - smartredis-fortran - smartredis-main - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis libraries - set(SMARTREDIS_LIBRARIES - smartredis-fortran - smartredis-main - ) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${MPI_INCLUDE_PATH} - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis) +find_package(smartredis-fortran) # Stuff the example_utils into a library to enable building the examples in parallel add_library(example_utils STATIC example_utils.F90) @@ -133,5 +63,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) ${SMARTREDIS_LIBRARIES} MPI::MPI_Fortran example_utils + smartredis + smartredis-fortran ) endforeach() diff --git a/examples/serial/c/CMakeLists.txt b/examples/serial/c/CMakeLists.txt index 7c9070f4..d2fcaa6b 100644 --- a/examples/serial/c/CMakeLists.txt +++ b/examples/serial/c/CMakeLists.txt @@ -35,53 +35,9 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../..") -include(smartredis_defs) - -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../../install/") -endif() # Locate dependencies -add_library(smartredis-main ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} -) - -# Select libraries for build -if (STATIC_BUILD) - # Mark that SmartRedis requires the C++ linker - set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - ) - - # Static builds have an extra dependency on the Pthreads library - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - smartredis-main - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis library - set(SMARTREDIS_LIBRARIES - smartredis-main - ) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) - +find_package(smartredis) # Define all the examples to be built list(APPEND EXECUTABLES example_put_unpack_1D @@ -97,6 +53,6 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_c_serial - ${SMARTREDIS_LIBRARIES} + smartredis ) endforeach() diff --git a/examples/serial/cpp/CMakeLists.txt b/examples/serial/cpp/CMakeLists.txt index e15ef965..70c802eb 100644 --- a/examples/serial/cpp/CMakeLists.txt +++ b/examples/serial/cpp/CMakeLists.txt @@ -34,40 +34,8 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../..") -include(smartredis_defs) -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../../install/") -endif() - -# Locate dependencies -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) - -# Select libraries for build -if (STATIC_BUILD) - # Static builds have an extra dependency on the Pthreads library - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - ${SR_LIB} - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis library - set(SMARTREDIS_LIBRARIES ${SR_LIB}) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis) # Define all the examples to be built list(APPEND EXECUTABLES @@ -86,6 +54,6 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_cpp_serial - ${SMARTREDIS_LIBRARIES} + smartredis ) endforeach() diff --git a/examples/serial/fortran/CMakeLists.txt b/examples/serial/fortran/CMakeLists.txt index 27a7f9e6..4c78583e 100644 --- a/examples/serial/fortran/CMakeLists.txt +++ b/examples/serial/fortran/CMakeLists.txt @@ -35,77 +35,9 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../..") -include(smartredis_defs) -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../../install/") -endif() - -# Locate dependencies -# . Main SmartRedis Library (C/C++ based) -add_library(smartredis-main ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} -) -# . SmartRedis Fortran Library (Fortran based) -add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_FTN_LIB ${SMARTREDIS_FORTRAN_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-fortran PROPERTIES - IMPORTED_LOCATION ${SR_FTN_LIB} -) - -# Select libraries for build -if (STATIC_BUILD) - # The CMake "preferred" approach only seems to work with the GNU - # compiler. We will streamline this in the future - if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - # Mark that SmartRedis requires the C++ linker - set_target_properties(smartredis-main PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - ) - set_target_properties(smartredis-fortran PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "FORTRAN" - ) - else() # Tested with PGI, Intel - # For other compilers, don't set languages so that CMake will use the Fortran linker (default) - - # Add the stdc++ linker flag - set(CMAKE_EXE_LINKER_FLAGS "-lstdc++ ${CMAKE_EXE_LINKER_FLAGS}") - endif() - - # Static builds have an extra dependency on the Pthreads library - # The order of libraries here is crucial to get dependencies covered - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - smartredis-fortran - smartredis-main - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis libraries - set(SMARTREDIS_LIBRARIES - smartredis-fortran - smartredis-main - ) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis) +find_package(smartredis-fortran) # Define all the examples to be built list(APPEND EXECUTABLES @@ -122,6 +54,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_fortran_serial - ${SMARTREDIS_LIBRARIES} + smartredis + smartredis-fortran ) endforeach() diff --git a/images/Dockerfile b/images/Dockerfile index 4d44fc61..60687515 100644 --- a/images/Dockerfile +++ b/images/Dockerfile @@ -50,12 +50,6 @@ COPY . /usr/local/src/SmartRedis # Compile and install WORKDIR /usr/local/src/SmartRedis RUN pip3 install --upgrade pip -RUN make clobber && make lib SR_FORTRAN=ON SR_PYTHON=ON +RUN make clobber && make lib SR_FORTRAN=ON SR_PYTHON=ON SR_PREFIX=/usr/local RUN pip install . && rm -rf ~/.cache/pip \ && rm -rf build tests examples images utils third-party doc - -# Copy install files and directories to /usr/local/lib and -# usr/local/include and delete unnecessary build files -RUN cp -r /usr/local/src/SmartRedis/install/lib/* /usr/local/lib/ && \ - mkdir /usr/local/include/smartredis && \ - cp -r /usr/local/src/SmartRedis/install/include/* /usr/local/include/smartredis/ diff --git a/tests/c/CMakeLists.txt b/tests/c/CMakeLists.txt index fdcc7672..8564fbf0 100644 --- a/tests/c/CMakeLists.txt +++ b/tests/c/CMakeLists.txt @@ -34,52 +34,7 @@ enable_language(C) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../..") -include(smartredis_defs) - -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../install/") -endif() - -# Locate dependencies -add_library(smartredis-main ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} -) - -# Select libraries for build -if (STATIC_BUILD) - # Mark that SmartRedis requires the C++ linker - set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - ) - - # Static builds have an extra dependency on the Pthreads library - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - smartredis-main - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis library - set(SMARTREDIS_LIBRARIES - smartredis-main - ) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis REQUIRED) # Define all the tests to be built list(APPEND EXECUTABLES @@ -101,6 +56,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_c_test - ${SMARTREDIS_LIBRARIES} + smartredis ) -endforeach() + target_include_directories(${EXECUTABLE}_c_test PRIVATE ${smartredis_INCLUDE_DIR}) +endforeach() \ No newline at end of file diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index e649dd8a..fdceb261 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -34,44 +34,11 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../..") -include(smartredis_defs) +find_package(smartredis REQUIRED) # Bring in the Catch2 unit-tests add_subdirectory(unit-tests) -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../install/") -endif() - -# Locate dependencies -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) - -# Select libraries for build -if (STATIC_BUILD) - # Static builds have an extra dependency on the Pthreads library - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - ${SR_LIB} - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis library - set(SMARTREDIS_LIBRARIES ${SR_LIB}) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) - # Define all the tests to be built list(APPEND EXECUTABLES client_test_dataset @@ -108,6 +75,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_cpp_test - ${SMARTREDIS_LIBRARIES} + smartredis ) + target_include_directories(${EXECUTABLE}_cpp_test PRIVATE ${smartredis_INCLUDE_DIR}) endforeach() diff --git a/tests/docker/c/CMakeLists.txt b/tests/docker/c/CMakeLists.txt index c21a0165..ea5a5c13 100644 --- a/tests/docker/c/CMakeLists.txt +++ b/tests/docker/c/CMakeLists.txt @@ -34,11 +34,7 @@ set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_BUILD_TYPE DEBUG) set(CMAKE_CXX_STANDARD 17) -find_library(SR_LIB smartredis) - -include_directories(SYSTEM - /usr/local/include/smartredis -) +find_package(smartredis) # Build executables add_executable(docker_test_c @@ -47,4 +43,4 @@ add_executable(docker_test_c set_target_properties(docker_test_c PROPERTIES OUTPUT_NAME docker_test ) -target_link_libraries(docker_test_c ${SR_LIB} pthread) +target_link_libraries(docker_test_c smartredis pthread) diff --git a/tests/docker/c/Dockerfile b/tests/docker/c/Dockerfile index 2d22b178..edd2baf2 100644 --- a/tests/docker/c/Dockerfile +++ b/tests/docker/c/Dockerfile @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -FROM smartredis +FROM smartredis:local # Copy source and build files into the container COPY ./CMakeLists.txt /usr/local/src/DockerTest/ diff --git a/tests/docker/cpp/CMakeLists.txt b/tests/docker/cpp/CMakeLists.txt index 3a9c2834..3a78f36f 100644 --- a/tests/docker/cpp/CMakeLists.txt +++ b/tests/docker/cpp/CMakeLists.txt @@ -34,18 +34,12 @@ set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_BUILD_TYPE DEBUG) set(CMAKE_CXX_STANDARD 17) -find_library(SR_LIB smartredis) - -include_directories(SYSTEM - /usr/local/include/smartredis -) - +find_package(smartredis) # Build executables - add_executable(docker_test_cpp docker_test.cpp ) set_target_properties(docker_test_cpp PROPERTIES OUTPUT_NAME docker_test ) -target_link_libraries(docker_test_cpp ${SR_LIB} pthread) +target_link_libraries(docker_test_cpp smartredis pthread) diff --git a/tests/docker/cpp/Dockerfile b/tests/docker/cpp/Dockerfile index 345531b5..bf0473ac 100644 --- a/tests/docker/cpp/Dockerfile +++ b/tests/docker/cpp/Dockerfile @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -FROM smartredis +FROM smartredis:local # Copy source and build files into the container COPY ./CMakeLists.txt /usr/local/src/DockerTest/ diff --git a/tests/docker/fortran/CMakeLists.txt b/tests/docker/fortran/CMakeLists.txt index a73f8af8..8de9f08b 100644 --- a/tests/docker/fortran/CMakeLists.txt +++ b/tests/docker/fortran/CMakeLists.txt @@ -36,17 +36,8 @@ SET(CMAKE_C_STANDARD 99) set(CMAKE_BUILD_TYPE Debug) # Locate dependencies -find_library(SR_LIB smartredis REQUIRED) -find_library(SR_FTN_LIB smartredis-fortran REQUIRED) -set(SMARTREDIS_LIBRARIES - ${SR_LIB} - ${SR_FTN_LIB} -) - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include/smartredis -) +find_package(smartredis) +find_package(smartredis-fortran) # Build the test add_executable(docker_test_fortran @@ -55,4 +46,4 @@ add_executable(docker_test_fortran set_target_properties(docker_test_fortran PROPERTIES OUTPUT_NAME docker_test ) -target_link_libraries(docker_test_fortran ${SMARTREDIS_LIBRARIES} pthread) +target_link_libraries(docker_test_fortran smartredis smartredis-fortran pthread) diff --git a/tests/docker/fortran/Dockerfile b/tests/docker/fortran/Dockerfile index 664d0e5a..911daca6 100644 --- a/tests/docker/fortran/Dockerfile +++ b/tests/docker/fortran/Dockerfile @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -FROM smartredis +FROM smartredis:local # Install Fortran compiler RUN apt-get update && \ diff --git a/tests/fortran/CMakeLists.txt b/tests/fortran/CMakeLists.txt index bc82e3ee..58414290 100644 --- a/tests/fortran/CMakeLists.txt +++ b/tests/fortran/CMakeLists.txt @@ -34,77 +34,8 @@ enable_language(Fortran) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../..") -include(smartredis_defs) - -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../install/") -endif() - -# Locate dependencies -# . Main SmartRedis Library (C/C++ based) -add_library(smartredis-main ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-main PROPERTIES - IMPORTED_LOCATION ${SR_LIB} -) -# . SmartRedis Fortran Library (Fortran based) -add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} IMPORTED) -find_library(SR_FTN_LIB ${SMARTREDIS_FORTRAN_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) -set_target_properties(smartredis-fortran PROPERTIES - IMPORTED_LOCATION ${SR_FTN_LIB} -) - -# Select libraries for build -if (STATIC_BUILD) - # The CMake "preferred" approach only seems to work with the GNU - # compiler. We will streamline this in the future - if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - # Mark that SmartRedis requires the C++ linker - set_target_properties(smartredis-main PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - ) - set_target_properties(smartredis-fortran PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "FORTRAN" - ) - else() # Tested with PGI, Intel - # For other compilers, don't set languages so that CMake will use the Fortran linker (default) - - # Add the stdc++ linker flag - set(CMAKE_EXE_LINKER_FLAGS "-lstdc++ ${CMAKE_EXE_LINKER_FLAGS}") - endif() - - # Static builds have an extra dependency on the Pthreads library - # The order of libraries here is crucial to get dependencies covered - find_package(Threads REQUIRED) - set(SMARTREDIS_LIBRARIES - smartredis-fortran - smartredis-main - Threads::Threads - ) -else() - # Shared builds only need the SmartRedis libraries - set(SMARTREDIS_LIBRARIES - smartredis-fortran - smartredis-main - ) -endif() - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis REQUIRED) +find_package(smartredis-fortran REQUIRED) # Stuff the test_utils into a library to enable parallel builds add_library(test-utils STATIC test_utils.F90) @@ -130,13 +61,14 @@ list(APPEND EXECUTABLES # Build the tests foreach(EXECUTABLE ${EXECUTABLES}) - add_executable(${EXECUTABLE}_fortran_test - ${EXECUTABLE}.F90 - ) + add_executable(${EXECUTABLE}_fortran_test + ${EXECUTABLE}.F90 + ) set_target_properties(${EXECUTABLE}_fortran_test PROPERTIES OUTPUT_NAME ${EXECUTABLE} ) - target_link_libraries(${EXECUTABLE}_fortran_test - ${SMARTREDIS_LIBRARIES} test-utils - ) -endforeach() + target_link_libraries(${EXECUTABLE}_fortran_test + smartredis smartredis-fortran test-utils + ) + target_include_directories(${EXECUTABLE}_fortran_test PRIVATE ${smartredis_INCLUDE_DIR} ${smartredis-fortran_INCLUDE_DIR}) +endforeach() \ No newline at end of file From 001b34c6c596027cd5dd47a175c038d8c286f660 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Fri, 21 Jun 2024 16:43:56 +0000 Subject: [PATCH 10/25] Replace smartredis target with variable --- CMakeLists.txt | 13 ++++++++----- tests/cpp/unit-tests/CMakeLists.txt | 24 +++--------------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15ccf7b3..0ee3707f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,9 +235,9 @@ else () # Shared library build target_include_directories(${SMARTREDIS_LIB} PUBLIC $ ) - target_link_libraries(smartredis PRIVATE libhiredis libredis++ Threads::Threads) + target_link_libraries(${SMARTREDIS_LIB} PRIVATE libhiredis libredis++ Threads::Threads) add_custom_command( - TARGET smartredis + TARGET ${SMARTREDIS_LIB} POST_BUILD COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig ${CMAKE_INSTALL_PREFIX}/lib/cmake VERBATIM @@ -273,14 +273,17 @@ if (SR_FORTRAN) set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/include") # Fortran library add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} ${FORTRAN_SRC}) - add_dependencies(smartredis-fortran smartredis) + add_dependencies(smartredis-fortran ${SMARTREDIS_LIB}) + target_include_directories(smartredis-fortran PUBLIC + $ + ) set_target_properties(smartredis-fortran PROPERTIES SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} ) set_target_properties(smartredis-fortran PROPERTIES OUTPUT_NAME ${SMARTREDIS_FORTRAN_LIB} ) - target_link_libraries(smartredis-fortran PUBLIC smartredis) +target_link_libraries(smartredis-fortran PUBLIC ${SMARTREDIS_LIB}) # Install dynamic library and headers install(TARGETS smartredis-fortran EXPORT smartredis-fortran-targets @@ -359,4 +362,4 @@ if(SR_FORTRAN) ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran ) -endif() \ No newline at end of file +endif() diff --git a/tests/cpp/unit-tests/CMakeLists.txt b/tests/cpp/unit-tests/CMakeLists.txt index 28a6d2c9..0b0d9c06 100644 --- a/tests/cpp/unit-tests/CMakeLists.txt +++ b/tests/cpp/unit-tests/CMakeLists.txt @@ -35,33 +35,15 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../..") -include(smartredis_defs) set(THREADS_PREFER_PTHREAD_FLAG ON) -# Assume by default that users should link against the -# install directory in this repository -if(NOT DEFINED SMARTREDIS_INSTALL_PATH) - set(SMARTREDIS_INSTALL_PATH "../../../install/") -endif() - -# Locate dependencies -find_library(SR_LIB ${SMARTREDIS_LIB} - PATHS ${SMARTREDIS_INSTALL_PATH}/lib NO_DEFAULT_PATH - REQUIRED - ${SMARTREDIS_LINK_MODE} -) find_package(Threads REQUIRED) - -# Define include directories for header files -include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include -) +find_package(smartredis) # Identify source files to be built into the CPP Catch2 unit tests file(GLOB UNIT_TESTS CONFIGURE_DEPENDS ./*.cpp) # Build the CPP Catch2 unit tests add_executable(cpp_unit_tests ${UNIT_TESTS}) -target_link_libraries(cpp_unit_tests PUBLIC ${SR_LIB} PRIVATE Threads::Threads) +target_link_libraries(cpp_unit_tests PRIVATE smartredis Threads::Threads) +target_include_directories(cpp_unit_tests PRIVATE ${smartredis_INCLUDE_DIR}) From 8f532a4bc5e7b837506190b401455a2ec5f79650 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Fri, 21 Jun 2024 10:49:39 -0700 Subject: [PATCH 11/25] Simplify the CMakeLists --- CMakeLists.txt | 294 +++++++++---------- Makefile | 167 +++++------ conftest.py | 20 +- setup.py | 6 +- smartredis_defs.cmake | 87 ------ tests/CMakeLists.txt | 4 +- tests/c/test_c_client.py | 4 +- tests/cpp/test_cpp_client.py | 4 +- tests/cpp/unit-tests/test_unit_cpp_client.py | 4 +- tests/fortran/test_fortran_client.py | 4 +- 10 files changed, 249 insertions(+), 345 deletions(-) delete mode 100644 smartredis_defs.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ee3707f..a9d9cfbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,37 +24,56 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Enable setting version in the project statement + if (POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif (POLICY CMP0048) -# Project definition for the SmartRedis project +## Project definition for the SmartRedis cmake_minimum_required(VERSION 3.13) project(SmartRedis VERSION "0.5.3") -include(GNUInstallDirs) - -# Configure options for the SmartRedis project -option(SR_PYTHON "Build the python module" OFF) -option(SR_FORTRAN "Build the fortran client library" OFF) -option(SR_PEDANTIC "Build with pickiest compiler settings" OFF) - -set(CMAKE_CXX_STANDARD 17) +## Specify options for the SmartRedis project +option(BUILD_FORTRAN "Build the fortran client library" OFF) +option(BUILD_PYTHON "Build the python module" OFF) +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) +option(PEDANTIC "Build with pickiest compiler settings" OFF) if(NOT DEFINED CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) endif() +if(NOT DEFINED CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() + +## Cmake Modules +include(GNUInstallDirs) +include(ExternalProject) +include(CMakePrintHelpers) +if(BUILD_PYTHON) + include(FetchContent) +endif() + +## Configure the remainder of the builder +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_VISIBILITY_PRESET default) set(THREADS_PREFER_PTHREAD_FLAG ON) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}) -include(smartredis_defs) -# If we want to use Fortran, we have to tell CMake to use it -if (SR_FORTRAN) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + set(CMAKE_BUILD_TYPE Debug) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU")) + add_compile_options(--coverage) + add_link_options(--coverage) + else() + message(WARNING "A coverage build was specified, but the CMAKE compiler is not GCC") + endif() +endif() + +if (BUILD_FORTRAN) enable_language(Fortran) + set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/include") endif() -# Include external libraries -include(ExternalProject) +## Include external libraries # Add hiredis as an external project ExternalProject_Add(hiredis GIT_REPOSITORY https://github.com/redis/hiredis.git @@ -75,13 +94,18 @@ set(hiredis_binary_dir ${binary_dir}) add_library(libhiredis UNKNOWN IMPORTED) add_dependencies(libhiredis hiredis) +## Note: These ExternalProjects need to be installed into the +## SmartRedis install directory since there are variants of the +## header files that are chosen based on various configuration +## options. Any extra artifacts should be removed in the +## POST_BUILD step + # Set hiredis properties set_target_properties(libhiredis PROPERTIES IMPORTED_LOCATION ${hiredis_binary_dir}/libhiredis.a INTERFACE_INCLUDE_DIRECTORIES ${hiredis_source_dir} ) -include(CMakePrintHelpers) cmake_print_variables(hiredis_source_dir) # Define redis++ as an external project ExternalProject_Add(redis++ @@ -110,19 +134,16 @@ set_target_properties(libredis++ PROPERTIES ) # Add pybind11 -include(FetchContent) -FetchContent_Declare( - pybind11 - GIT_REPOSITORY https://github.com/pybind/pybind11 - GIT_TAG v2.11.1 -) +if(BUILD_PYTHON) + FetchContent_Declare( + pybind11 + GIT_REPOSITORY https://github.com/pybind/pybind11 + GIT_TAG v2.11.1 + ) +endif(BUILD_PYTHON) # For now, we only support Pedantic on the main library build. -# If/when we fine-tune the examples and test cases, move this block -# to smartredis_defs.cmake -# Note: -Wextra can be added after unused parameters are addressed - -if (SR_PEDANTIC) +if (PEDANTIC) if( (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC") @@ -136,7 +157,7 @@ if (SR_PEDANTIC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -pedantic") set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all -warn error") else() - message(WARNING "SR_PEDANTIC not supported for ${CMAKE_CXX_COMPILER_ID}") + message(WARNING "PEDANTIC not supported for ${CMAKE_CXX_COMPILER_ID}") message(WARNING ${CMAKE_CXX_COMPILER_ID}) endif() if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") @@ -147,7 +168,7 @@ endif() find_package(Threads REQUIRED) # Define source code that goes into the SmartRedis library -set(CLIENT_SRC +list(APPEND C_CPP_SRC src/c/c_client.cpp src/c/c_configoptions.cpp src/c/c_dataset.cpp @@ -187,66 +208,50 @@ set(CLIENT_SRC src/cpp/threadpool.cpp src/cpp/utility.cpp ) +set(FORTRAN_SRC + src/fortran/errors.F90 + src/fortran/client.F90 + src/fortran/configoptions.F90 + src/fortran/dataset.F90 + src/fortran/fortran_c_interop.F90 + src/fortran/logcontext.F90 + src/fortran/logger.F90 +) +## Include headers from redis++ and hiredis. Included as system libraries +## to avoid the pedantic options from detecting errors in those files include_directories(SYSTEM $) -# Build the main SmartRedis library -if (STATIC_BUILD) - set(TEMP_LIB_NAME sr${SR_STATIC_NAME_SUFFIX}-static) - set(TEMP_LIB_FULLNAME lib${TEMP_LIB_NAME}.a) - set(SR_LIB_INSTALL_PATH ${CMAKE_SOURCE_DIR}/include/lib) - add_library(${TEMP_LIB_NAME} ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) - add_dependencies(${TEMP_LIB_NAME} libhiredis libredis++) - set_target_properties(${TEMP_LIB_NAME} PROPERTIES - SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} - ) - set_target_properties(${TEMP_LIB_NAME} PROPERTIES - OUTPUT_NAME ${TEMP_LIB_NAME} - ) - target_link_libraries(${TEMP_LIB_NAME} PRIVATE libhiredis libredis++ Threads::Threads) - - # Merge SmartRedis static library with dependenciee - # . Create a sacrificial dummy file so we have source to make a target against - set(DUMMY_FILE ${CMAKE_BINARY_DIR}/merge-dummy.cpp) - file( - WRITE ${DUMMY_FILE} - "// Life, the universe, and everything!\nstatic int __attribute__((unused)) sr_magic_number = 42;\n" - ) - add_library(${SMARTREDIS_LIB} STATIC ${DUMMY_FILE}) - set(STATIC_LIB_COMPONENTS ${SR_LIB_INSTALL_PATH}/${TEMP_LIB_FULLNAME} ${EXT_CLIENT_LIBRARIES}) - - # . Archive the static libraries together into a thin library - add_custom_command( - TARGET ${SMARTREDIS_LIB} - POST_BUILD - COMMAND rm -f lib${SMARTREDIS_LIB}.a && mkdir -p ${SR_LIB_INSTALL_PATH} && cp ${CMAKE_BINARY_DIR}/${TEMP_LIB_FULLNAME} ${SR_LIB_INSTALL_PATH} && ar crT lib${SMARTREDIS_LIB}.a ${STATIC_LIB_COMPONENTS} && rm ${CMAKE_INSTALL_PREFIX}/lib/{libhiredis.a,libredis++.a} - VERBATIM - COMMENT "Creating lib${SMARTREDIS_LIB}.a and removing intermediate libraries" - ) - -else () # Shared library build - add_library(${SMARTREDIS_LIB} ${SMARTREDIS_LINK_MODE} ${CLIENT_SRC}) - add_dependencies(${SMARTREDIS_LIB} libhiredis libredis++) - set_target_properties(${SMARTREDIS_LIB} PROPERTIES - SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} - ) - set_target_properties(${SMARTREDIS_LIB} PROPERTIES - OUTPUT_NAME ${SMARTREDIS_LIB} - ) - target_include_directories(${SMARTREDIS_LIB} PUBLIC - $ - ) - target_link_libraries(${SMARTREDIS_LIB} PRIVATE libhiredis libredis++ Threads::Threads) - add_custom_command( - TARGET ${SMARTREDIS_LIB} - POST_BUILD - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig ${CMAKE_INSTALL_PREFIX}/lib/cmake - VERBATIM - COMMENT "Removing intermediate static libraries" - ) +## Build the main SmartRedis library +cmake_print_variables(BUILD_SHARED_LIBS) +set(CLIENT_SRC ${C_CPP_SRC}) +add_library(smartredis ${CLIENT_SRC}) +if(BUILD_SHARED_LIBS) + set_target_properties(smartredis PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() +target_link_libraries(smartredis PRIVATE libhiredis libredis++ Threads::Threads) +add_dependencies(smartredis libhiredis libredis++) +target_include_directories(smartredis PUBLIC + $ +) +add_custom_command( + TARGET smartredis + POST_BUILD + # Delete hiredis artifacts + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/build + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/cmake + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig + # Delete redis++ artifacts + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/share/cmake/redis++ + VERBATIM + COMMENT "Removing artifacts from dependencies" +) + install( - TARGETS ${SMARTREDIS_LIB} + TARGETS smartredis EXPORT smartredis-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} @@ -257,67 +262,6 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -# Build the Fortran library -if (SR_FORTRAN) - set(FORTRAN_SRC - src/fortran/errors.F90 - src/fortran/client.F90 - src/fortran/configoptions.F90 - src/fortran/dataset.F90 - src/fortran/fortran_c_interop.F90 - src/fortran/logcontext.F90 - src/fortran/logger.F90 - ) - include_directories(src/fortran) - # Note the following has to be before ANY add_library command) - set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/include") - # Fortran library - add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} ${FORTRAN_SRC}) - add_dependencies(smartredis-fortran ${SMARTREDIS_LIB}) - target_include_directories(smartredis-fortran PUBLIC - $ - ) - set_target_properties(smartredis-fortran PROPERTIES - SUFFIX ${SMARTREDIS_LINK_LIBRARY_SUFFIX} - ) - set_target_properties(smartredis-fortran PROPERTIES - OUTPUT_NAME ${SMARTREDIS_FORTRAN_LIB} - ) -target_link_libraries(smartredis-fortran PUBLIC ${SMARTREDIS_LIB}) - # Install dynamic library and headers - install(TARGETS smartredis-fortran - EXPORT smartredis-fortran-targets - LIBRARY DESTINATION lib - ) -endif() - -# Build the Python library for SmartRedis -if(SR_PYTHON) - message("-- Python client build enabled") - FetchContent_GetProperties(pybind11) - if(NOT pybind11_POPULATED) - FetchContent_Populate(pybind11) - endif() - add_subdirectory(${pybind11_SOURCE_DIR} ${pybind11_BINARY_DIR}) - pybind11_add_module(smartredisPy - src/python/src/pyclient.cpp - src/python/src/pyconfigoptions.cpp - src/python/src/pydataset.cpp - src/python/src/pylogcontext.cpp - src/python/src/pysrobject.cpp - ${CLIENT_SRC} - src/python/bindings/bind.cpp) - add_dependencies(smartredisPy libhiredis libredis++) - target_link_libraries(smartredisPy PRIVATE libhiredis libredis++) - target_include_directories(smartredisPy PUBLIC - $ - ) - install(TARGETS smartredisPy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) - install(TARGETS smartredisPy LIBRARY DESTINATION ../src/python/module/smartredis) -else() - message("-- Skipping Python client build") -endif() - install(EXPORT smartredis-targets FILE smartredis.cmake DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis @@ -338,28 +282,70 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/smartredisConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/smartredisConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis - ) +) -if(SR_FORTRAN) - install(EXPORT smartredis-fortran-targets +# Build the libraries for the Fortran Client +if (BUILD_FORTRAN) + add_library(smartredis-fortran ${SMARTREDIS_LINK_MODE} ${FORTRAN_SRC}) + add_dependencies(smartredis-fortran smartredis) + target_link_libraries(smartredis-fortran PUBLIC smartredis) + target_include_directories(smartredis PUBLIC + $ + ) + install( + TARGETS smartredis-fortran + EXPORT smartredis-fortran-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + + install( + EXPORT smartredis-fortran-targets FILE smartredis-fortran.cmake DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran ) - include(CMakePackageConfigHelpers) configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.smartredis-fortran.cmake.in smartredis-fortranConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran ) - write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfigVersion.cmake" VERSION "${VERSION}" COMPATIBILITY AnyNewerVersion ) - install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran + ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/smartredis-fortranConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran ) +else() + message("-- Skipping Fortran client build") endif() + +# Build the Python library for SmartRedis +if(BUILD_PYTHON) + message("-- Python client build enabled") + FetchContent_GetProperties(pybind11) + if(NOT pybind11_POPULATED) + FetchContent_Populate(pybind11) + endif() + add_subdirectory(${pybind11_SOURCE_DIR} ${pybind11_BINARY_DIR}) + pybind11_add_module(smartredisPy + ${C_CPP_SRC} + src/python/src/pyclient.cpp + src/python/src/pyconfigoptions.cpp + src/python/src/pydataset.cpp + src/python/src/pylogcontext.cpp + src/python/src/pysrobject.cpp + src/python/bindings/bind.cpp + ) + add_dependencies(smartredisPy libhiredis libredis++) + target_link_libraries(smartredisPy PRIVATE libhiredis libredis++) + target_include_directories(smartredisPy PUBLIC + $ + ) + install(TARGETS smartredisPy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS smartredisPy LIBRARY DESTINATION ../src/python/module/smartredis) +else() + message("-- Skipping Python client build") +endif() \ No newline at end of file diff --git a/Makefile b/Makefile index 50b889ad..b56bfacf 100644 --- a/Makefile +++ b/Makefile @@ -31,12 +31,12 @@ CWD := $(shell pwd) # Build variables NPROC := $(shell nproc 2>/dev/null || python -c "import multiprocessing as mp; print (mp.cpu_count())" 2>/dev/null || echo 4) -SR_BUILD := Release -SR_LINK := Shared -SR_PEDANTIC := OFF -SR_FORTRAN := OFF -SR_PYTHON := OFF -SR_PREFIX := $(CWD)/install +INSTALL_PREFIX := $(CWD)/install +BUILD_FORTRAN := OFF +BUILD_PYTHON := OFF +BUILD_SHARED_LIBS := ON +BUILD_TYPE := Release +PEDANTIC := OFF # Test dependencies REDIS_URL := https://github.com/redis/redis.git @@ -58,8 +58,12 @@ SR_TEST_NODES := 3 SR_TEST_REDISAI_VER := v1.2.7 SR_TEST_DEVICE := cpu SR_TEST_PYTEST_FLAGS := -vv -s - - +ifeq ($(BUILD_SHARED_LIBS),ON) + SR_LINK_DIR = shared +else + SR_LINK_DIR = static +endif +SR_TEST_INSTALL_PREFIX = $(CWD)/install/$(BUILD_TYPE)/$(SR_LINK_DIR) # Do not remove this block. It is used by the 'help' rule when # constructing the help output. # help: @@ -78,17 +82,14 @@ help: # help: These variables affect the way that the SmartRedis library is built. Each # help: has several options; the first listed is the default. Use by appending # help: the variable name and setting after the make target, e.g. -# help: make lib SR_BUILD=Debug SR_LINK=Static SR_FORTRAN=ON +# help: make lib BUILD_TYPE=Debug Static BUILD_FORTRAN=ON # help: -# help: SR_BUILD {Release, Debug, Coverage} -- optimization level for the build -# help: SR_LINK {Shared, Static} -- linkage for the SmartRedis library -# help: SR_PEDANTIC {OFF, ON} -- GNU only; enable pickiest compiler settings, +# help: BUILD_TYPE {Release, Debug, Coverage} -- optimization level for the build +# help: BUILD_SHARED_LIBS {OFF, ON} -- If OFF, build static libraries, otherwise shared libraries +# help: PEDANTIC {OFF, ON} -- GNU only; enable pickiest compiler settings, # help: currently fails due to warnings on newer GNU versions -# help: SR_FORTRAN {OFF, ON} -- Enable/disable build of Fortran library -# help: SR_PYTHON {OFF, ON} -- Enable/disable build of Python library -# help: DEP_CC, DEP_CXX -- Set the C and C++ compilers used to compile dependencies. -# help: This will generally be gcc/g++ due to the build system's -# help: assuming the GCC toolchain +# help: BUILD_FORTRAN {OFF, ON} -- Enable/disable build of Fortran library +# help: BUILD_PYTHON {OFF, ON} -- Enable/disable build of Python library # help: # help: Test variables # help: -------------- @@ -96,7 +97,7 @@ help: # help: These variables affect the way that the SmartRedis library is tested. Each # help: has several options; the first listed is the default. Use by appending # help: the variable name and setting after the make target, e.g. -# help: make test SR_BUILD=Debug SR_LINK=Static SR_FORTRAN=ON +# help: make test BUILD_TYPE=Debug BUILD_SHARED_LIBS=off BUILD_FORTRAN=ON # help: # help: SR_TEST_REDIS_MODE {Clustered, Standalone} -- type of Redis backend launched for tests # help: SR_TEST_PORT (Default: 6379) -- first port for Redis server(s) @@ -113,32 +114,32 @@ help: .PHONY: lib lib: lib: - @cmake -S . -B build/$(SR_BUILD) -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ - -DSR_PEDANTIC=$(SR_PEDANTIC) -DSR_FORTRAN=$(SR_FORTRAN) -DSR_PYTHON=$(SR_PYTHON) \ - -DCMAKE_INSTALL_PREFIX=$(SR_PREFIX) - @cmake --build build/$(SR_BUILD) -- -j $(NPROC) - @cmake --install build/$(SR_BUILD) + @cmake -S . -B build/$(BUILD_TYPE) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -DPEDANTIC=$(PEDANTIC) -DBUILD_FORTRAN=$(BUILD_FORTRAN) -DBUILD_PYTHON=$(BUILD_PYTHON) \ + -DCMAKE_INSTALL_PREFIX=$(INSTALL_PREFIX) + @cmake --build build/$(BUILD_TYPE) -- -j $(NPROC) + @cmake --install build/$(BUILD_TYPE) # help: lib-with-fortran - Build SmartRedis C/C++/Python and Fortran clients into a dynamic library .PHONY: lib-with-fortran -lib-with-fortran: SR_FORTRAN=ON +lib-with-fortran: BUILD_FORTRAN=ON lib-with-fortran: lib # help: test-lib - Build SmartRedis clients into a dynamic library with least permissive compiler settings .PHONY: test-lib -test-lib: SR_PEDANTIC=ON +test-lib: PEDANTIC=ON +test-lib: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) test-lib: lib # help: test-lib-with-fortran - Build SmartRedis clients into a dynamic library with least permissive compiler settings .PHONY: test-lib-with-fortran -test-lib-with-fortran: SR_PEDANTIC=ON +test-lib-with-fortran: PEDANTIC=ON test-lib-with-fortran: lib-with-fortran # help: test-deps - Make SmartRedis testing dependencies .PHONY: test-deps test-deps: redis test-deps: redisAI -test-deps: catch2 test-deps: lcov # help: test-deps-gpu - Make SmartRedis GPU testing dependencies @@ -148,83 +149,84 @@ test-deps-gpu: test-deps # help: build-tests - build all tests (C, C++, Fortran) .PHONY: build-tests -build-tests: test-deps +build-tests: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-tests: test-lib - @cmake -S tests -B build/$(SR_BUILD)/tests/$(SR_LINK) \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ - -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK) -- -j $(NPROC) + @cmake -S tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR) \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR) -- -j $(NPROC) # help: build-test-cpp - build the C++ tests .PHONY: build-test-cpp -build-test-cpp: test-deps +build-test-cpp: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-test-cpp: test-lib - @cmake -S tests/cpp -B build/$(SR_BUILD)/tests/$(SR_LINK)/cpp \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis - @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/cpp -- -j $(NPROC) +build-test-cpp: catch2 + cmake -S tests/cpp -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis + cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp -- -j $(NPROC) # help: build-unit-test-cpp - build the C++ unit tests .PHONY: build-unit-test-cpp -build-unit-test-cpp: test-deps +build-unit-test-cpp: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-unit-test-cpp: test-lib - @cmake -S tests/cpp/unit-tests -B build/$(SR_BUILD)/tests/$(SR_LINK)/cpp/unit-tests \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis - @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/cpp/unit-tests -- -j $(NPROC) + @cmake -S tests/cpp/unit-tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp/unit-tests \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp/unit-tests -- -j $(NPROC) # help: build-test-c - build the C tests .PHONY: build-test-c -build-test-c: test-deps +build-test-c: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-test-c: test-lib - @cmake -S tests/c -B build/$(SR_BUILD)/tests/$(SR_LINK)/c \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis - @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/c -- -j $(NPROC) + @cmake -S tests/c -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/c \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/c -- -j $(NPROC) # help: build-test-fortran - build the Fortran tests .PHONY: build-test-fortran -build-test-fortran: test-deps -build-test-fortran: SR_FORTRAN=ON +build-test-fortran: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) +build-test-fortran: BUILD_FORTRAN=ON build-test-fortran: test-lib - @cmake -S tests/fortran -B build/$(SR_BUILD)/tests/$(SR_LINK)/fortran \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ - -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(SR_BUILD)/tests/$(SR_LINK)/fortran -- -j $(NPROC) + @cmake -S tests/fortran -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/fortran \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/fortran -- -j $(NPROC) # help: build-examples - build all examples (serial, parallel) .PHONY: build-examples build-examples: lib - @cmake -S examples -B build/$(SR_BUILD)/examples/$(SR_LINK) -DSR_BUILD=$(SR_BUILD) \ - -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ - -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(SR_BUILD)/examples/$(SR_LINK) -- -j $(NPROC) + @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR) -DBUILD_TYPE=$(BUILD_TYPE) \ + -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran + @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR) -- -j $(NPROC) # help: build-example-serial - buld serial examples .PHONY: build-example-serial build-example-serial: lib - @cmake -S examples/serial -B build/$(SR_BUILD)/examples/$(SR_LINK)/serial \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ - -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(SR_BUILD)/examples/$(SR_LINK)/serial + @cmake -S examples/serial -B build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/serial \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran + @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/serial # help: build-example-parallel - build parallel examples (requires MPI) .PHONY: build-example-parallel build-example-parallel: lib - @cmake -S examples/parallel -B build/$(SR_BUILD)/examples/$(SR_LINK)/parallel \ - -DSR_BUILD=$(SR_BUILD) -DSR_LINK=$(SR_LINK) -DSR_FORTRAN=$(SR_FORTRAN) \ - -Dsmartredis_DIR=$(SR_PREFIX)/share/cmake/smartredis \ - -Dsmartredis-fortran_DIR=$(SR_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(SR_BUILD)/examples/$(SR_LINK)/parallel + @cmake -S examples/parallel -B build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/parallel \ + -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran + @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/parallel # help: clean-deps - remove third-party deps @@ -237,6 +239,7 @@ clean-deps: .PHONY: clean clean: @git clean -X -f -d + rm -rf build # help: clobber - clean, remove deps, builds, (be careful) @@ -308,10 +311,10 @@ cov: # help: ------------ # Build Pytest flags to skip various subsets of the tests -ifeq ($(SR_PYTHON),OFF) +ifeq ($(BUILD_PYTHON),OFF) SKIP_PYTHON = --ignore ./tests/python endif -ifeq ($(SR_FORTRAN),OFF) +ifeq ($(BUILD_FORTRAN),OFF) SKIP_FORTRAN = --ignore ./tests/fortran endif SKIP_DOCKER := --ignore ./tests/docker @@ -334,8 +337,8 @@ define run_smartredis_tests_with_standalone_server echo "Running standalone tests" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --build $(SR_BUILD) --link $(SR_LINK) \ - --sr_fortran $(SR_FORTRAN) $(1) ; \ + --build_type $(BUILD_TYPE) --build_shared_libs $(BUILD_SHARED_LIBS) \ + --build_fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down standalone Redis server" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes 1 --stop && \ @@ -355,8 +358,8 @@ define run_smartredis_tests_with_clustered_server echo "Running clustered tests" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --build $(SR_BUILD) --link $(SR_LINK) \ - --sr_fortran $(SR_FORTRAN) $(1) ; \ + --build_type $(BUILD_TYPE) --build_shared_libs $(BUILD_SHARED_LIBS) \ + --build_fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down clustered Redis server" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) \ @@ -379,8 +382,8 @@ define run_smartredis_tests_with_uds_server echo "Running standalone tests with Unix Domain Socket connection" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --build $(SR_BUILD) --link $(SR_LINK) \ - --sr_fortran $(SR_FORTRAN) $(1) ; \ + --build_type $(BUILD_TYPE) --build_shared_libs $(BUILD_SHARED_LIBS) \ + --build_fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down standalone Redis server with Unix Domain Socket support" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes 1 \ @@ -428,7 +431,7 @@ test-verbose: # help: test-verbose-with-coverage - Build and run all tests [verbose-with-coverage] .PHONY: test-verbose-with-coverage -test-verbose-with-coverage: SR_BUILD := Coverage +test-verbose-with-coverage: BUILD_TYPE := Coverage test-verbose-with-coverage: test-deps test-verbose-with-coverage: build-tests test-verbose-with-coverage: SR_TEST_PYTEST_FLAGS := -vv -s @@ -460,7 +463,7 @@ unit-test-cpp: # help: test-py - run python tests .PHONY: test-py test-py: test-deps -test-py: SR_PYTHON := ON +test-py: BUILD_PYTHON := ON test-py: lib test-py: SR_TEST_PYTEST_FLAGS := -vv test-py: @@ -468,7 +471,7 @@ test-py: # help: test-fortran - run fortran tests .PHONY: test-fortran -test-fortran: SR_FORTRAN := ON +test-fortran: BUILD_FORTRAN := ON test-fortran: build-test-fortran test-fortran: SR_TEST_PYTEST_FLAGS := -vv -s test-fortran: @@ -477,7 +480,7 @@ test-fortran: # help: testpy-cov - run python tests with coverage .PHONY: testpy-cov testpy-cov: test-deps -testpy-cov: SR_PYTHON := ON +testpy-cov: BUILD_PYTHON := ON testpy-cov: SR_TEST_PYTEST_FLAGS := -vv testpy-cov: COV_FLAGS := --cov=./src/python/module/smartredis/ testpy-cov: diff --git a/conftest.py b/conftest.py index 1757dc7e..c39508ac 100644 --- a/conftest.py +++ b/conftest.py @@ -135,21 +135,23 @@ def create_torch_cnn(filepath=None): # Add a build type option to pytest command lines def pytest_addoption(parser): - parser.addoption("--build", action="store", default="Release") - parser.addoption("--link", action="store", default="Shared") - parser.addoption("--sr_fortran", action="store", default="OFF") + parser.addoption("--build_type", action="store", default="Release") + parser.addoption("--build_shared_libs", action="store", default="on") + parser.addoption("--build_fortran", action="store", default="OFF") # Fixture to retrieve the build type setting @pytest.fixture(scope="session") -def build(request): - return request.config.getoption("--build") +def build_type(request): + return request.config.getoption("--build_type") # Fixture to retrieve the link type setting @pytest.fixture(scope="session") -def link(request): - return request.config.getoption("--link") +def link_type(request): + if request.config.getoption("--build_shared_libs").lower() == "on": + return "shared" + return "static" # Fixture to retrieve the Fortran enablement setting @pytest.fixture(scope="session") -def sr_fortran(request): - return request.config.getoption("--sr_fortran") +def build_fortran(request): + return request.config.getoption("--build_fortran") diff --git a/setup.py b/setup.py index 428b9d4c..6c4b7ee5 100644 --- a/setup.py +++ b/setup.py @@ -78,10 +78,10 @@ def run(self): config_args = [ '-S.', f'-B{str(build_directory)}', - '-DSR_BUILD=' + cfg, - '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + str(build_directory), + '-DBUILD_TYPE=' + cfg, + '-DCMAKE_INSTALL_PREFIX=' + str(build_directory), '-DPYTHON_EXECUTABLE=' + sys.executable, - '-DSR_PYTHON=ON', + '-DBUILD_PYTHON=ON', ] subprocess.check_call( [self.cmake] + config_args, diff --git a/smartredis_defs.cmake b/smartredis_defs.cmake deleted file mode 100644 index ecbd2e36..00000000 --- a/smartredis_defs.cmake +++ /dev/null @@ -1,87 +0,0 @@ -# BSD 2-Clause License -# -# Copyright (c) 2021-2024, Hewlett Packard Enterprise -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Set defaults if variables are undefined -if(NOT DEFINED SR_BUILD) - set(SR_BUILD "Release") -endif() -if(NOT DEFINED SR_LINK) - set(SR_LINK "Shared") -endif() - -# Configure the CMake build based on the SR_BUILD selection -string(TOLOWER "${SR_BUILD}" srbuild_lowercase) -if(srbuild_lowercase STREQUAL "release") - set(CMAKE_BUILD_TYPE RELEASE) - set(SRLIB_NAME_SUFFIX "") - set(SR_STATIC_NAME_SUFFIX "-r") -elseif(srbuild_lowercase STREQUAL "debug") - set(CMAKE_BUILD_TYPE DEBUG) - set(SRLIB_NAME_SUFFIX "-debug") - set(SR_STATIC_NAME_SUFFIX "-d") -elseif(srbuild_lowercase STREQUAL "coverage") - set(CMAKE_BUILD_TYPE DEBUG) - set(SRLIB_NAME_SUFFIX "-coverage") - set(SR_STATIC_NAME_SUFFIX "-c") - if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU")) - add_compile_options(--coverage) - add_link_options(--coverage) - else() - message(WARNING "A coverage build was specified, but the CMAKE compiler is not GCC") - endif() -else() - message(FATAL_ERROR "Unrecognized build type (${SR_BUILD}) specified in SR_BUILD") -endif() - -# Configure CMake linkage on the SR_LINK selection -string(TOLOWER "${SR_LINK}" srlink_lowercase) -if(srlink_lowercase STREQUAL "static") - set(SMARTREDIS_LINK_MODE STATIC) - set(SMARTREDIS_LINK_LIBRARY_SUFFIX .a) - set(SMARTREDIS_LINK_SUFFIX "-static") - set(CMAKE_POSITION_INDEPENDENT_CODE ON) - set(STATIC_BUILD TRUE) - if(APPLE) - message(FATAL_ERROR "Static builds are not supported on MacOS") - endif(APPLE) -elseif(srlink_lowercase STREQUAL "shared") - set(SMARTREDIS_LINK_MODE SHARED) - set(SMARTREDIS_LINK_LIBRARY_SUFFIX .so) - set(SMARTREDIS_LINK_SUFFIX "") - set(STATIC_BUILD FALSE) -else() - message(FATAL_ERROR "Unrecognized link type (${SR_LINK}) specified in SR_LINK") -endif() - -# Identify the SmartRedis library names based on the build and link -set(SMARTREDIS_LIB smartredis${SRLIB_NAME_SUFFIX}${SMARTREDIS_LINK_SUFFIX}) -set(SMARTREDIS_LIB_FULLNAME - libsmartredis${SRLIB_NAME_SUFFIX}${SMARTREDIS_LINK_SUFFIX}${SMARTREDIS_LINK_LIBRARY_SUFFIX} -) -set(SMARTREDIS_FORTRAN_LIB smartredis-fortran${SRLIB_NAME_SUFFIX}${SMARTREDIS_LINK_SUFFIX}) -set(SMARTREDIS_FORTRAN_LIB_FULLNAME - libsmartredis-fortran${SRLIB_NAME_SUFFIX}${SMARTREDIS_LINK_SUFFIX}${SMARTREDIS_LINK_LIBRARY_SUFFIX} -) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cd0d8324..7e8eb6bc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,14 +31,14 @@ project(SmartSim-Tests) # Enable language support for the examples enable_language(C) enable_language(CXX) -if (SR_FORTRAN) +if (BUILD_FORTRAN) enable_language(Fortran) endif() # Bring in subdirectories add_subdirectory(c) add_subdirectory(cpp) -if (SR_FORTRAN) +if (BUILD_FORTRAN) add_subdirectory(fortran) endif() diff --git a/tests/c/test_c_client.py b/tests/c/test_c_client.py index bb9d5c74..258d385e 100644 --- a/tests/c/test_c_client.py +++ b/tests/c/test_c_client.py @@ -46,7 +46,7 @@ def get_test_names(): @pytest.mark.parametrize("test", get_test_names()) -def test_c_client(test, build, link): +def test_c_client(test, build_type, link_type): """This function actually runs the tests using the parameterization function provided in Pytest @@ -59,7 +59,7 @@ def test_c_client(test, build, link): # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build}/tests/{link}/{test}" + test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" cmd = [test] print(f"\nRunning test: {osp.basename(test)}") execute_cmd(cmd) diff --git a/tests/cpp/test_cpp_client.py b/tests/cpp/test_cpp_client.py index 99ce986a..0b9626fd 100644 --- a/tests/cpp/test_cpp_client.py +++ b/tests/cpp/test_cpp_client.py @@ -46,14 +46,14 @@ def get_test_names(): return test_names @pytest.mark.parametrize("test", get_test_names()) -def test_cpp_client(test, build, link): +def test_cpp_client(test, build_type, link_type): # Build the path to the test executable from the source file name # . keep only the last two parts of the path: (language, basename) test = "/".join(test.split("/")[-2:]) # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build}/tests/{link}/{test}" + test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" cmd = [test] print(f"\nRunning test: {osp.basename(test)}") execute_cmd(cmd) diff --git a/tests/cpp/unit-tests/test_unit_cpp_client.py b/tests/cpp/unit-tests/test_unit_cpp_client.py index 81516e83..6a8f48c4 100644 --- a/tests/cpp/unit-tests/test_unit_cpp_client.py +++ b/tests/cpp/unit-tests/test_unit_cpp_client.py @@ -46,12 +46,12 @@ def get_test_names(): @pytest.mark.parametrize("test", get_test_names()) -def test_unit_cpp_client(test, build, link): +def test_unit_cpp_client(test, build_type, link_type): # Build the path to the test executable from the source file name # . keep only the last three parts of the path: (language, unit-tests, basename) test = "/".join(test.split("/")[-3:]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build}/tests/{link}/{test}" + test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" cmd = [test] print(f"\nRunning test: {osp.basename(test)}") execute_cmd(cmd) diff --git a/tests/fortran/test_fortran_client.py b/tests/fortran/test_fortran_client.py index 057dbeb2..82d4e504 100644 --- a/tests/fortran/test_fortran_client.py +++ b/tests/fortran/test_fortran_client.py @@ -49,7 +49,7 @@ def get_test_names(): @pytest.mark.parametrize("test", get_test_names()) -def test_fortran_client(test, build, link): +def test_fortran_client(test, build_type, link_type): """This function actually runs the tests using the parameterization function provided in Pytest @@ -62,7 +62,7 @@ def test_fortran_client(test, build, link): # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build}/tests/{link}/{test}" + test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" cmd = [test] print(f"Running test: {osp.basename(test)}") print(f"Test command {' '.join(cmd)}") From 610d2eb97505371f7be05e363597dab2946d85e2 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Fri, 21 Jun 2024 15:49:31 -0700 Subject: [PATCH 12/25] Fight with object files again --- CMakeLists.txt | 21 ++++++------- Makefile | 52 +++++++++++++++------------------ tests/c/CMakeLists.txt | 1 + tests/cpp/CMakeLists.txt | 1 + tests/docker/c/Dockerfile | 2 +- tests/docker/cpp/Dockerfile | 2 +- tests/docker/fortran/Dockerfile | 2 +- tests/fortran/CMakeLists.txt | 3 +- 8 files changed, 42 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9d9cfbf..20ac8e14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_VISIBILITY_PRESET default) set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads) if(CMAKE_BUILD_TYPE STREQUAL Coverage) set(CMAKE_BUILD_TYPE Debug) @@ -74,6 +75,12 @@ if (BUILD_FORTRAN) endif() ## Include external libraries +## Note: These ExternalProjects need to be installed into the +## SmartRedis install directory since there are variants of the +## header files that are chosen based on various configuration +## options. Any extra artifacts should be removed in the +## POST_BUILD step + # Add hiredis as an external project ExternalProject_Add(hiredis GIT_REPOSITORY https://github.com/redis/hiredis.git @@ -90,16 +97,11 @@ ExternalProject_Add(hiredis ExternalProject_Get_Property(hiredis source_dir binary_dir) set(hiredis_source_dir ${source_dir}) set(hiredis_binary_dir ${binary_dir}) +file(GLOB hiredis_objs ${binary_dir}/CMakeFiles/hiredis.dir/*.o) add_library(libhiredis UNKNOWN IMPORTED) add_dependencies(libhiredis hiredis) -## Note: These ExternalProjects need to be installed into the -## SmartRedis install directory since there are variants of the -## header files that are chosen based on various configuration -## options. Any extra artifacts should be removed in the -## POST_BUILD step - # Set hiredis properties set_target_properties(libhiredis PROPERTIES IMPORTED_LOCATION ${hiredis_binary_dir}/libhiredis.a @@ -123,6 +125,7 @@ ExternalProject_Add(redis++ ExternalProject_Get_Property(redis++ source_dir binary_dir) set(redis++_source_dir ${source_dir}) set(redis++_binary_dir ${binary_dir}) +file(GLOB redis++_objs ${binary_dir}/CMakeFiles/redis++_static.dir/src/sw/redis++/*.o) cmake_print_variables(redis++_source_dir) add_library(libredis++ UNKNOWN IMPORTED) @@ -165,8 +168,6 @@ if (PEDANTIC) endif() endif() -find_package(Threads REQUIRED) - # Define source code that goes into the SmartRedis library list(APPEND C_CPP_SRC src/c/c_client.cpp @@ -226,11 +227,11 @@ include_directories(SYSTEM $) cmake_print_variables(BUILD_SHARED_LIBS) set(CLIENT_SRC ${C_CPP_SRC}) add_library(smartredis ${CLIENT_SRC}) +add_dependencies(smartredis hiredis redis++) if(BUILD_SHARED_LIBS) set_target_properties(smartredis PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() -target_link_libraries(smartredis PRIVATE libhiredis libredis++ Threads::Threads) -add_dependencies(smartredis libhiredis libredis++) +target_link_libraries(smartredis PRIVATE ${hiredis_objs} ${redis++_objs} PUBLIC Threads::Threads) target_include_directories(smartredis PUBLIC $ ) diff --git a/Makefile b/Makefile index b56bfacf..576858ae 100644 --- a/Makefile +++ b/Makefile @@ -34,8 +34,8 @@ NPROC := $(shell nproc 2>/dev/null || python -c "import multiprocessing as mp; p INSTALL_PREFIX := $(CWD)/install BUILD_FORTRAN := OFF BUILD_PYTHON := OFF -BUILD_SHARED_LIBS := ON BUILD_TYPE := Release +LINK_TYPE := shared PEDANTIC := OFF # Test dependencies @@ -58,12 +58,12 @@ SR_TEST_NODES := 3 SR_TEST_REDISAI_VER := v1.2.7 SR_TEST_DEVICE := cpu SR_TEST_PYTEST_FLAGS := -vv -s -ifeq ($(BUILD_SHARED_LIBS),ON) - SR_LINK_DIR = shared +ifeq ($(LINK_TYPE), shared) + BUILD_SHARED_LIBS=on else - SR_LINK_DIR = static + BUILD_SHARED_LIBS=off endif -SR_TEST_INSTALL_PREFIX = $(CWD)/install/$(BUILD_TYPE)/$(SR_LINK_DIR) +SR_TEST_INSTALL_PREFIX = $(CWD)/install/$(BUILD_TYPE)/$(SR_LINK_TYPE) # Do not remove this block. It is used by the 'help' rule when # constructing the help output. # help: @@ -85,7 +85,7 @@ help: # help: make lib BUILD_TYPE=Debug Static BUILD_FORTRAN=ON # help: # help: BUILD_TYPE {Release, Debug, Coverage} -- optimization level for the build -# help: BUILD_SHARED_LIBS {OFF, ON} -- If OFF, build static libraries, otherwise shared libraries +# help: LINK_TYPE {shared, static} -- type of linking for the smartredis libraries # help: PEDANTIC {OFF, ON} -- GNU only; enable pickiest compiler settings, # help: currently fails due to warnings on newer GNU versions # help: BUILD_FORTRAN {OFF, ON} -- Enable/disable build of Fortran library @@ -128,7 +128,6 @@ lib-with-fortran: lib # help: test-lib - Build SmartRedis clients into a dynamic library with least permissive compiler settings .PHONY: test-lib test-lib: PEDANTIC=ON -test-lib: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) test-lib: lib # help: test-lib-with-fortran - Build SmartRedis clients into a dynamic library with least permissive compiler settings @@ -149,84 +148,81 @@ test-deps-gpu: test-deps # help: build-tests - build all tests (C, C++, Fortran) .PHONY: build-tests -build-tests: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-tests: test-lib - @cmake -S tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR) \ +build-tests: catch2 + @cmake -S tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE) \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR) -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE) -- -j $(NPROC) # help: build-test-cpp - build the C++ tests .PHONY: build-test-cpp -build-test-cpp: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-test-cpp: test-lib build-test-cpp: catch2 - cmake -S tests/cpp -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp \ + cmake -S tests/cpp -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis - cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp -- -j $(NPROC) + cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp -- -j $(NPROC) # help: build-unit-test-cpp - build the C++ unit tests .PHONY: build-unit-test-cpp -build-unit-test-cpp: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-unit-test-cpp: test-lib - @cmake -S tests/cpp/unit-tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp/unit-tests \ +build-unit-test-cpp: catch2 + @cmake -S tests/cpp/unit-tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp/unit-tests \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/cpp/unit-tests -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp/unit-tests -- -j $(NPROC) # help: build-test-c - build the C tests .PHONY: build-test-c -build-test-c: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-test-c: test-lib - @cmake -S tests/c -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/c \ + @cmake -S tests/c -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/c \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/c -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/c -- -j $(NPROC) # help: build-test-fortran - build the Fortran tests .PHONY: build-test-fortran -build-test-fortran: INSTALL_PREFIX=$(SR_TEST_INSTALL_PREFIX) build-test-fortran: BUILD_FORTRAN=ON build-test-fortran: test-lib - @cmake -S tests/fortran -B build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/fortran \ + @cmake -S tests/fortran -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/fortran \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_DIR)/fortran -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/fortran -- -j $(NPROC) # help: build-examples - build all examples (serial, parallel) .PHONY: build-examples build-examples: lib - @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR) -DBUILD_TYPE=$(BUILD_TYPE) \ + @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE) -DBUILD_TYPE=$(BUILD_TYPE) \ -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR) -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE) -- -j $(NPROC) # help: build-example-serial - buld serial examples .PHONY: build-example-serial build-example-serial: lib - @cmake -S examples/serial -B build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/serial \ + @cmake -S examples/serial -B build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/serial \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/serial + @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/serial # help: build-example-parallel - build parallel examples (requires MPI) .PHONY: build-example-parallel build-example-parallel: lib - @cmake -S examples/parallel -B build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/parallel \ + @cmake -S examples/parallel -B build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/parallel \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_DIR)/parallel + @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/parallel # help: clean-deps - remove third-party deps diff --git a/tests/c/CMakeLists.txt b/tests/c/CMakeLists.txt index 8564fbf0..94d3160b 100644 --- a/tests/c/CMakeLists.txt +++ b/tests/c/CMakeLists.txt @@ -35,6 +35,7 @@ enable_language(C) set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) find_package(smartredis REQUIRED) +find_package(Threads REQUIRED) # Define all the tests to be built list(APPEND EXECUTABLES diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index fdceb261..6073c662 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -35,6 +35,7 @@ enable_language(CXX) set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) find_package(smartredis REQUIRED) +find_package(Threads) # Bring in the Catch2 unit-tests add_subdirectory(unit-tests) diff --git a/tests/docker/c/Dockerfile b/tests/docker/c/Dockerfile index edd2baf2..2d22b178 100644 --- a/tests/docker/c/Dockerfile +++ b/tests/docker/c/Dockerfile @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -FROM smartredis:local +FROM smartredis # Copy source and build files into the container COPY ./CMakeLists.txt /usr/local/src/DockerTest/ diff --git a/tests/docker/cpp/Dockerfile b/tests/docker/cpp/Dockerfile index bf0473ac..345531b5 100644 --- a/tests/docker/cpp/Dockerfile +++ b/tests/docker/cpp/Dockerfile @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -FROM smartredis:local +FROM smartredis # Copy source and build files into the container COPY ./CMakeLists.txt /usr/local/src/DockerTest/ diff --git a/tests/docker/fortran/Dockerfile b/tests/docker/fortran/Dockerfile index 911daca6..664d0e5a 100644 --- a/tests/docker/fortran/Dockerfile +++ b/tests/docker/fortran/Dockerfile @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -FROM smartredis:local +FROM smartredis # Install Fortran compiler RUN apt-get update && \ diff --git a/tests/fortran/CMakeLists.txt b/tests/fortran/CMakeLists.txt index 58414290..fa5a53bf 100644 --- a/tests/fortran/CMakeLists.txt +++ b/tests/fortran/CMakeLists.txt @@ -36,6 +36,7 @@ set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) find_package(smartredis REQUIRED) find_package(smartredis-fortran REQUIRED) +find_package(Threads REQUIRED) # Stuff the test_utils into a library to enable parallel builds add_library(test-utils STATIC test_utils.F90) @@ -68,7 +69,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_fortran_test - smartredis smartredis-fortran test-utils + smartredis smartredis-fortran test-utils Threads::Threads ) target_include_directories(${EXECUTABLE}_fortran_test PRIVATE ${smartredis_INCLUDE_DIR} ${smartredis-fortran_INCLUDE_DIR}) endforeach() \ No newline at end of file From 6972d4a441394157c92943902dffa5fdab00f867 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Mon, 24 Jun 2024 17:53:03 +0000 Subject: [PATCH 13/25] Resolve dependencies for static build --- CMakeLists.txt | 66 +++++++++++++++++++++++------------- tests/c/CMakeLists.txt | 1 - tests/cpp/CMakeLists.txt | 1 - tests/fortran/CMakeLists.txt | 1 - 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20ac8e14..1c389eaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,8 @@ project(SmartRedis VERSION "0.5.3") option(BUILD_FORTRAN "Build the fortran client library" OFF) option(BUILD_PYTHON "Build the python module" OFF) option(BUILD_SHARED_LIBS "Build using shared libraries" ON) -option(PEDANTIC "Build with pickiest compiler settings" OFF) -if(NOT DEFINED CMAKE_INSTALL_PREFIX) +option(PEDANTIC "Build with strictest compiler settings" OFF) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) endif() if(NOT DEFINED CMAKE_BUILD_TYPE) @@ -97,9 +97,8 @@ ExternalProject_Add(hiredis ExternalProject_Get_Property(hiredis source_dir binary_dir) set(hiredis_source_dir ${source_dir}) set(hiredis_binary_dir ${binary_dir}) -file(GLOB hiredis_objs ${binary_dir}/CMakeFiles/hiredis.dir/*.o) -add_library(libhiredis UNKNOWN IMPORTED) +add_library(libhiredis STATIC IMPORTED) add_dependencies(libhiredis hiredis) # Set hiredis properties @@ -125,10 +124,9 @@ ExternalProject_Add(redis++ ExternalProject_Get_Property(redis++ source_dir binary_dir) set(redis++_source_dir ${source_dir}) set(redis++_binary_dir ${binary_dir}) -file(GLOB redis++_objs ${binary_dir}/CMakeFiles/redis++_static.dir/src/sw/redis++/*.o) -cmake_print_variables(redis++_source_dir) -add_library(libredis++ UNKNOWN IMPORTED) + +add_library(libredis++ STATIC IMPORTED) add_dependencies(libredis++ redis++) set_target_properties(libredis++ PROPERTIES @@ -231,25 +229,47 @@ add_dependencies(smartredis hiredis redis++) if(BUILD_SHARED_LIBS) set_target_properties(smartredis PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() -target_link_libraries(smartredis PRIVATE ${hiredis_objs} ${redis++_objs} PUBLIC Threads::Threads) target_include_directories(smartredis PUBLIC $ ) -add_custom_command( - TARGET smartredis - POST_BUILD - # Delete hiredis artifacts - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/build - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/cmake - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig - # Delete redis++ artifacts - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig - COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/share/cmake/redis++ - VERBATIM - COMMENT "Removing artifacts from dependencies" -) + +if (BUILD_SHARED_LIBS) + target_link_libraries(smartredis PRIVATE libhiredis libredis++ Threads::Threads) + add_custom_command( + TARGET smartredis + POST_BUILD + # Delete hiredis artifacts + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/build + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/cmake + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig + # Delete redis++ artifacts + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/share/cmake/redis++ + VERBATIM + COMMENT "Removing artifacts from dependencies" + ) +else() + + target_link_libraries(smartredis PUBLIC + ${CMAKE_INSTALL_PREFIX}/lib/libhiredis.a + ${CMAKE_INSTALL_PREFIX}/lib/libredis++.a + ) + add_custom_command( + TARGET smartredis + POST_BUILD + # Delete hiredis artifacts + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/build + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/cmake + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig + # Delete redis++ artifacts + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig + COMMAND rm -rf ${CMAKE_INSTALL_PREFIX}/share/cmake/redis++ + VERBATIM + COMMENT "Removing artifacts from dependencies" + ) +endif() install( TARGETS smartredis diff --git a/tests/c/CMakeLists.txt b/tests/c/CMakeLists.txt index 94d3160b..8564fbf0 100644 --- a/tests/c/CMakeLists.txt +++ b/tests/c/CMakeLists.txt @@ -35,7 +35,6 @@ enable_language(C) set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) find_package(smartredis REQUIRED) -find_package(Threads REQUIRED) # Define all the tests to be built list(APPEND EXECUTABLES diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index 6073c662..fdceb261 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -35,7 +35,6 @@ enable_language(CXX) set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) find_package(smartredis REQUIRED) -find_package(Threads) # Bring in the Catch2 unit-tests add_subdirectory(unit-tests) diff --git a/tests/fortran/CMakeLists.txt b/tests/fortran/CMakeLists.txt index fa5a53bf..c80e6a0a 100644 --- a/tests/fortran/CMakeLists.txt +++ b/tests/fortran/CMakeLists.txt @@ -36,7 +36,6 @@ set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) find_package(smartredis REQUIRED) find_package(smartredis-fortran REQUIRED) -find_package(Threads REQUIRED) # Stuff the test_utils into a library to enable parallel builds add_library(test-utils STATIC test_utils.F90) From 7feca48ef244e2b4dae3dd53891f1a12ec2ada73 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Mon, 24 Jun 2024 18:54:11 +0000 Subject: [PATCH 14/25] Rename old variables in testing infrastructure --- .github/workflows/run_tests.yml | 13 +++++++------ examples/test_examples.py | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 2331492c..7f8412a0 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -176,22 +176,23 @@ jobs: - name: Build and install test dependencies run: | - make test-deps && - echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/install/lib" >> $GITHUB_ENV + make test-deps # Make sure the examples work - name: Run examples run: | - make test-examples SR_FORTRAN=ON SR_PYTHON=ON SR_LINK=$LINK_TYPE \ - SR_TEST_PORT=7000 SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} + make test-examples BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE \ + SR_TEST_PORT=7000 SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ + INSTALL_PREFIX=$PWD/install/$LINK_TYPE # Run the tests using various DB deployments - name: Run tests run: | make test-verbose-with-coverage \ COV_FLAGS="--cov=./src/python/module/smartredis/ --cov-report=xml --cov-append" \ - SR_FORTRAN=ON SR_PYTHON=ON SR_TEST_REDIS_MODE=All SR_TEST_PORT=7000 SR_LINK=$LINK_TYPE \ - SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} + BUILD_FORTRAN=ON BUILD_PYTHON=ON SR_TEST_REDIS_MODE=All SR_TEST_PORT=7000 LINK_TYPE=$LINK_TYPE \ + SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ + INSTALL_PREFIX=$PWD/install/$LINK_TYPE # Process and upload code coverage (Python was collected during pytest) - name: Collect coverage from C/C++/Fortran testers diff --git a/examples/test_examples.py b/examples/test_examples.py index 09b520e3..61eb8d0a 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -48,8 +48,8 @@ def get_test_names(): return test_names @pytest.mark.parametrize("test", get_test_names()) -def test_example(test, build, sr_fortran, link): - if (sr_fortran == "ON" or ".F90" not in test): +def test_example(test, build_type, build_fortran, link_type): + if (build_fortran == "ON" or ".F90" not in test): # Build the path to the test executable from the source file name # . keep only the last three parts of the path: (parallel/serial, language, basename) test = "/".join(test.split("/")[-3:]) @@ -57,7 +57,7 @@ def test_example(test, build, sr_fortran, link): # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build}/examples/{link}/{test}" + test = f"{getcwd()}/build/{build_type}/examples/{link_type}/{test}" cmd = ["mpirun", "-n", "2"] if "parallel" in test else [] cmd += [test] print(f"Running test: {osp.basename(test)}") From 1fdf02ea01ce8984ee1923ca9449a4c0c99c3aa0 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Mon, 24 Jun 2024 19:04:03 +0000 Subject: [PATCH 15/25] Fix docker tests --- images/Dockerfile | 5 ++--- tests/docker/c/Dockerfile | 2 +- tests/docker/cpp/Dockerfile | 2 +- tests/docker/fortran/Dockerfile | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/images/Dockerfile b/images/Dockerfile index 60687515..3c9bf2b9 100644 --- a/images/Dockerfile +++ b/images/Dockerfile @@ -33,9 +33,8 @@ FROM ubuntu:22.04 as builder RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -q -y --no-install-recommends \ ca-certificates git \ - make cmake gcc g++ libc6-dev python3 libpython3-dev pip gfortran && \ + make cmake gcc g++ libc6-dev python3 libpython3-dev pip gfortran python-is-python3 && \ rm -rf /var/lib/apt/lists/* -RUN ln -s /usr/bin/python3 /usr/bin/python # Get source code from current clone COPY . /usr/local/src/SmartRedis @@ -50,6 +49,6 @@ COPY . /usr/local/src/SmartRedis # Compile and install WORKDIR /usr/local/src/SmartRedis RUN pip3 install --upgrade pip -RUN make clobber && make lib SR_FORTRAN=ON SR_PYTHON=ON SR_PREFIX=/usr/local +RUN make clobber && make lib BUILD_FORTRAN=ON BUILD_PYTHON=ON INSTALL_PREFIX=/usr/local RUN pip install . && rm -rf ~/.cache/pip \ && rm -rf build tests examples images utils third-party doc diff --git a/tests/docker/c/Dockerfile b/tests/docker/c/Dockerfile index 2d22b178..bfec934e 100644 --- a/tests/docker/c/Dockerfile +++ b/tests/docker/c/Dockerfile @@ -36,7 +36,7 @@ COPY ./test_docker.c /usr/local/src/DockerTest/ WORKDIR /usr/local/src/DockerTest # Run CMake and make -RUN mkdir build && cd build && cmake .. && make && cd ../ +RUN mkdir build && cd build && cmake .. -Dsmartredis_DIR=/usr/local/share/cmake/smartredis && make && cd ../ # Default command for container execution CMD ["/usr/local/src/DockerTest/build/docker_test"] \ No newline at end of file diff --git a/tests/docker/cpp/Dockerfile b/tests/docker/cpp/Dockerfile index 345531b5..513975b0 100644 --- a/tests/docker/cpp/Dockerfile +++ b/tests/docker/cpp/Dockerfile @@ -36,7 +36,7 @@ COPY ./docker_test.cpp /usr/local/src/DockerTest/ WORKDIR /usr/local/src/DockerTest # Run CMake and make -RUN mkdir build && cd build && cmake .. && make && cd ../ +RUN mkdir build && cd build && cmake .. -Dsmartredis_DIR=/usr/local/share/cmake/smartredis && make && cd ../ # Default command for container execution CMD ["/usr/local/src/DockerTest/build/docker_test"] \ No newline at end of file diff --git a/tests/docker/fortran/Dockerfile b/tests/docker/fortran/Dockerfile index 664d0e5a..2bd64226 100644 --- a/tests/docker/fortran/Dockerfile +++ b/tests/docker/fortran/Dockerfile @@ -42,7 +42,7 @@ COPY ./test_docker.F90 /usr/local/src/DockerTest/ WORKDIR /usr/local/src/DockerTest # Run CMake and make -RUN mkdir build && cd build && cmake .. && make && cd ../ +RUN mkdir build && cd build && cmake .. -Dsmartredis_DIR=/usr/local/share/cmake/smartredis && make && cd ../ # Default command for container execution CMD ["/usr/local/src/DockerTest/build/docker_test"] \ No newline at end of file From 66c60af24c8a7148372283e93ed1d01c149624ef Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 25 Jun 2024 00:46:05 +0000 Subject: [PATCH 16/25] fix some errors in testing --- Makefile | 69 ++++++++++--------- conftest.py | 70 ++++++++++++++------ examples/test_examples.py | 52 +++------------ tests/c/CMakeLists.txt | 4 +- tests/c/test_c_client.py | 50 +++----------- tests/cpp/CMakeLists.txt | 1 + tests/cpp/test_cpp_client.py | 57 ++++------------ tests/cpp/unit-tests/CMakeLists.txt | 6 +- tests/cpp/unit-tests/test_unit_cpp_client.py | 64 ++---------------- tests/fortran/test_fortran_client.py | 54 +++------------ 10 files changed, 143 insertions(+), 284 deletions(-) diff --git a/Makefile b/Makefile index 576858ae..0c2d488e 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,8 @@ CWD := $(shell pwd) # Build variables NPROC := $(shell nproc 2>/dev/null || python -c "import multiprocessing as mp; print (mp.cpu_count())" 2>/dev/null || echo 4) INSTALL_PREFIX := $(CWD)/install +TEST_PREFIX := $(CWD)/tests/ +EXAMPLES_PREFIX := $(CWD)/examples/bin BUILD_FORTRAN := OFF BUILD_PYTHON := OFF BUILD_TYPE := Release @@ -63,7 +65,7 @@ ifeq ($(LINK_TYPE), shared) else BUILD_SHARED_LIBS=off endif -SR_TEST_INSTALL_PREFIX = $(CWD)/install/$(BUILD_TYPE)/$(SR_LINK_TYPE) +SR_TEST_INSTALL_PREFIX = $(CWD)/install/$(BUILD_TYPE)/$(LINK_TYPE) # Do not remove this block. It is used by the 'help' rule when # constructing the help output. # help: @@ -149,80 +151,90 @@ test-deps-gpu: test-deps # help: build-tests - build all tests (C, C++, Fortran) .PHONY: build-tests build-tests: test-lib -build-tests: catch2 - @cmake -S tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE) \ - -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ - -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ - -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE) -- -j $(NPROC) +build-tests: build-unit-test-cpp +build-tests: build-test-cpp +build-tests: build-test-c +build-tests: build-test-fortran # help: build-test-cpp - build the C++ tests .PHONY: build-test-cpp build-test-cpp: test-lib build-test-cpp: catch2 - cmake -S tests/cpp -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp \ + @cmake -S tests/cpp -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ - -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis - cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp -- -j $(NPROC) + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/cpp + @cmake --build build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp -- -j $(NPROC) + @cmake --install build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp # help: build-unit-test-cpp - build the C++ unit tests .PHONY: build-unit-test-cpp build-unit-test-cpp: test-lib build-unit-test-cpp: catch2 - @cmake -S tests/cpp/unit-tests -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp/unit-tests \ + @cmake -S tests/cpp/unit-tests -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp/unit-tests \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/cpp \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/cpp/unit-tests -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp/unit-tests -- -j $(NPROC) + @cmake --install build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp/unit-tests # help: build-test-c - build the C tests .PHONY: build-test-c build-test-c: test-lib - @cmake -S tests/c -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/c \ + @cmake -S tests/c -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/c \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ - -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/c -- -j $(NPROC) + -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ + -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/c + @cmake --build build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/c -- -j $(NPROC) + @cmake --install build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/c # help: build-test-fortran - build the Fortran tests .PHONY: build-test-fortran build-test-fortran: BUILD_FORTRAN=ON build-test-fortran: test-lib - @cmake -S tests/fortran -B build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/fortran \ + @cmake -S tests/fortran -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/fortran \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/fortran \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/tests/$(SR_LINK_TYPE)/fortran -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/fortran -- -j $(NPROC) + @cmake --install build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/fortran # help: build-examples - build all examples (serial, parallel) .PHONY: build-examples build-examples: lib - @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE) -DBUILD_TYPE=$(BUILD_TYPE) \ + @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE) -DBUILD_TYPE=$(BUILD_TYPE) \ -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -DCMAKE_INSTALL_PREFIX=$(EXAMPLES_PREFIX) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE) -- -j $(NPROC) + @cmake --build build/$(BUILD_TYPE)/examples/$(LINK_TYPE) -- -j $(NPROC) + @cmake --install build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/ # help: build-example-serial - buld serial examples .PHONY: build-example-serial build-example-serial: lib - @cmake -S examples/serial -B build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/serial \ + @cmake -S examples/serial -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/serial \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -DCMAKE_INSTALL_PREFIX=$(EXAMPLES_PREFIX) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/serial + @cmake --build build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/serial # help: build-example-parallel - build parallel examples (requires MPI) .PHONY: build-example-parallel build-example-parallel: lib - @cmake -S examples/parallel -B build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/parallel \ + @cmake -S examples/parallel -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/parallel \ -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -DCMAKE_INSTALL_PREFIX=$(EXAMPLES_PREFIX) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran - @cmake --build build/$(BUILD_TYPE)/examples/$(SR_LINK_TYPE)/parallel + @cmake --build build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/parallel # help: clean-deps - remove third-party deps @@ -333,8 +345,7 @@ define run_smartredis_tests_with_standalone_server echo "Running standalone tests" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --build_type $(BUILD_TYPE) --build_shared_libs $(BUILD_SHARED_LIBS) \ - --build_fortran $(BUILD_FORTRAN) $(1) ; \ + --bin-path $(TEST_PREFIX) --build-fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down standalone Redis server" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes 1 --stop && \ @@ -352,10 +363,9 @@ define run_smartredis_tests_with_clustered_server python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes $(SR_TEST_NODES) \ --rai $(SR_TEST_REDISAI_VER) --device $(SR_TEST_DEVICE) && \ echo "Running clustered tests" && \ - PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ + PYTHONFAULTHANDLER=1 python -s -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --build_type $(BUILD_TYPE) --build_shared_libs $(BUILD_SHARED_LIBS) \ - --build_fortran $(BUILD_FORTRAN) $(1) ; \ + --bin-path $(TEST_PREFIX) --build-fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down clustered Redis server" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) \ @@ -378,8 +388,7 @@ define run_smartredis_tests_with_uds_server echo "Running standalone tests with Unix Domain Socket connection" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --build_type $(BUILD_TYPE) --build_shared_libs $(BUILD_SHARED_LIBS) \ - --build_fortran $(BUILD_FORTRAN) $(1) ; \ + --bin-path $(TEST_PREFIX) --build-fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down standalone Redis server with Unix Domain Socket support" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes 1 \ diff --git a/conftest.py b/conftest.py index c39508ac..66efc193 100644 --- a/conftest.py +++ b/conftest.py @@ -24,6 +24,9 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import pathlib +from subprocess import Popen, PIPE, TimeoutExpired + import pytest import numpy as np import torch @@ -133,25 +136,54 @@ def create_torch_cnn(filepath=None): str_model = buffer.getvalue() return str_model -# Add a build type option to pytest command lines +# Add a options to pytest command lines def pytest_addoption(parser): - parser.addoption("--build_type", action="store", default="Release") - parser.addoption("--build_shared_libs", action="store", default="on") - parser.addoption("--build_fortran", action="store", default="OFF") + parser.addoption( + "--bin-path", + action="store", + default=pathlib.Path.cwd() / "build" / "Release" / "tests" + ) + parser.addoption( + "--build-fortran", + action="store", + default=0 + ) # Fixture to retrieve the build type setting -@pytest.fixture(scope="session") -def build_type(request): - return request.config.getoption("--build_type") - -# Fixture to retrieve the link type setting -@pytest.fixture(scope="session") -def link_type(request): - if request.config.getoption("--build_shared_libs").lower() == "on": - return "shared" - return "static" - -# Fixture to retrieve the Fortran enablement setting -@pytest.fixture(scope="session") -def build_fortran(request): - return request.config.getoption("--build_fortran") +@pytest.fixture(scope="module") +def bin_path(request): + return pathlib.Path(request.config.getoption("--bin-path")) + +@pytest.fixture() +def execute_cmd(): + def _execute_cmd(cmd_list, run_path=pathlib.Path.cwd()): + """Execute a command """ + + # spawning the subprocess and connecting to its output + proc = Popen( + cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=run_path) + try: + out, err = proc.communicate(timeout=120) + if out: + print("OUTPUT:", out.decode("utf-8")) + if err: + print("ERROR:", err.decode("utf-8")) + assert(proc.returncode == 0) + except UnicodeDecodeError: + output, errs = proc.communicate() + print("ERROR:", errs.decode("utf-8")) + assert(False) + except TimeoutExpired: + proc.kill() + output, errs = proc.communicate() + print("TIMEOUT: test timed out after test timeout limit of 120 seconds") + print("OUTPUT:", output.decode("utf-8")) + print("ERROR:", errs.decode("utf-8")) + assert(False) + except Exception: + proc.kill() + output, errs = proc.communicate() + print("OUTPUT:", output.decode("utf-8")) + print("ERROR:", errs.decode("utf-8")) + assert(False) + return _execute_cmd \ No newline at end of file diff --git a/examples/test_examples.py b/examples/test_examples.py index 61eb8d0a..19589cff 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -26,21 +26,20 @@ import pytest from os import path as osp -from os import getcwd from glob import glob -from subprocess import Popen, PIPE, TimeoutExpired +import pathlib import time RANKS = 1 -TEST_PATH = osp.dirname(osp.abspath(__file__)) +TEST_PATH = pathlib.parent(pathlib.Path(__file__).resolve()) def get_test_names(): """Obtain test names by globbing for client_test Add tests manually if necessary """ - glob_path_1 = osp.join(TEST_PATH, "*/*/example*") - glob_path_2 = osp.join(TEST_PATH, "*/*/smartredis*") - test_names = glob(glob_path_1) + glob(glob_path_2) + glob_path_1 = TEST_PATH.glob("*/*/example*") + glob_path_2 = TEST_PATH.glob("*/*/smartredis*") + test_names = list(glob_path_1) + list(glob_path_2) test_names = list(filter(lambda test: test.find('example_utils') == -1, test_names)) test_names = list(filter(lambda test: test.find('.py') == -1, test_names)) test_names = [(pytest.param(test, @@ -48,7 +47,7 @@ def get_test_names(): return test_names @pytest.mark.parametrize("test", get_test_names()) -def test_example(test, build_type, build_fortran, link_type): +def test_example(test, bin_path, build_fortran, execute_cmd): if (build_fortran == "ON" or ".F90" not in test): # Build the path to the test executable from the source file name # . keep only the last three parts of the path: (parallel/serial, language, basename) @@ -57,45 +56,12 @@ def test_example(test, build_type, build_fortran, link_type): # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build_type}/examples/{link_type}/{test}" + test = bin_path / test cmd = ["mpirun", "-n", "2"] if "parallel" in test else [] cmd += [test] - print(f"Running test: {osp.basename(test)}") + print(f"\nRunning test: {test.basename()}") print(f"Test command {' '.join(cmd)}") - execute_cmd(cmd, test_subdir) + execute_cmd(cmd, pathlib.Path.cwd()/test_subdir) time.sleep(1) else: print (f"Skipping Fortran test {test}") - -def execute_cmd(cmd_list, test_subdir): - """Execute a command """ - - # spawning the subprocess and connecting to its output - run_path = TEST_PATH + "/" + test_subdir - print(f"Test path: {run_path}") - proc = Popen( - cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=run_path) - try: - out, err = proc.communicate(timeout=120) - if out: - print("OUTPUT:", out.decode("utf-8")) - if err: - print("ERROR:", err.decode("utf-8")) - assert(proc.returncode == 0) - except UnicodeDecodeError: - output, errs = proc.communicate() - print("ERROR:", errs.decode("utf-8")) - assert(False) - except TimeoutExpired: - proc.kill() - output, errs = proc.communicate() - print("TIMEOUT: test timed out after test timeout limit of 120 seconds") - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) - except Exception: - proc.kill() - output, errs = proc.communicate() - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) diff --git a/tests/c/CMakeLists.txt b/tests/c/CMakeLists.txt index 8564fbf0..f678af5d 100644 --- a/tests/c/CMakeLists.txt +++ b/tests/c/CMakeLists.txt @@ -59,4 +59,6 @@ foreach(EXECUTABLE ${EXECUTABLES}) smartredis ) target_include_directories(${EXECUTABLE}_c_test PRIVATE ${smartredis_INCLUDE_DIR}) -endforeach() \ No newline at end of file + list(APPEND test-targets ${EXECUTABLE}) + install( ${EXECUTABLE_c_test}) +endforeach() diff --git a/tests/c/test_c_client.py b/tests/c/test_c_client.py index 258d385e..8c35fef9 100644 --- a/tests/c/test_c_client.py +++ b/tests/c/test_c_client.py @@ -24,29 +24,26 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import pathlib import pytest -from os import path as osp -from os import getcwd -from glob import glob -from subprocess import Popen, PIPE, TimeoutExpired import time RANKS = 1 -TEST_PATH = osp.dirname(osp.abspath(__file__)) +TEST_PATH = pathlib.Path(__file__).resolve().parent def get_test_names(): """Obtain test names by globbing for client_test Add tests manually if necessary """ - glob_path = osp.join(TEST_PATH, "client_test*") - test_names = glob(glob_path) + glob_path = TEST_PATH + test_names = glob_path.glob("client_test*.c") test_names = [(pytest.param(test, - id=osp.basename(test))) for test in test_names] + id=test.name)) for test in test_names] return test_names @pytest.mark.parametrize("test", get_test_names()) -def test_c_client(test, build_type, link_type): +def test_c_client(test, bin_path, execute_cmd): """This function actually runs the tests using the parameterization function provided in Pytest @@ -59,39 +56,8 @@ def test_c_client(test, build_type, link_type): # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" + test = bin_path / test cmd = [test] - print(f"\nRunning test: {osp.basename(test)}") + print(f"\nRunning test: {test.basename()}") execute_cmd(cmd) time.sleep(1) - -def execute_cmd(cmd_list): - """Execute a command """ - - # spawning the subprocess and connecting to its output - proc = Popen( - cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=TEST_PATH) - try: - out, err = proc.communicate(timeout=120) - if out: - print("OUTPUT:", out.decode("utf-8")) - if err: - print("ERROR:", err.decode("utf-8")) - assert(proc.returncode == 0) - except UnicodeDecodeError: - output, errs = proc.communicate() - print("ERROR:", errs.decode("utf-8")) - assert(False) - except TimeoutExpired: - proc.kill() - output, errs = proc.communicate() - print("TIMEOUT: test timed out after test timeout limit of 120 seconds") - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) - except Exception: - proc.kill() - output, errs = proc.communicate() - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index fdceb261..0d9bfc21 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -78,4 +78,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) smartredis ) target_include_directories(${EXECUTABLE}_cpp_test PRIVATE ${smartredis_INCLUDE_DIR}) + install(TARGETS ${EXECUTABLE}_cpp_test) endforeach() diff --git a/tests/cpp/test_cpp_client.py b/tests/cpp/test_cpp_client.py index 0b9626fd..f6661a52 100644 --- a/tests/cpp/test_cpp_client.py +++ b/tests/cpp/test_cpp_client.py @@ -24,6 +24,7 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import pathlib import pytest from os import path as osp from os import getcwd @@ -32,60 +33,28 @@ import time RANKS = 1 -TEST_PATH = osp.dirname(osp.abspath(__file__)) +TEST_PATH = pathlib.Path(__file__).resolve().parent def get_test_names(): """Obtain test names by globbing for client_test Add tests manually if necessary """ - glob_path = osp.join(TEST_PATH, "client_test*") - test_names = glob(glob_path) - test_names = list(filter(lambda test: test.find('.h') == -1, test_names)) + glob_path = TEST_PATH + test_names = glob_path.glob("client_test*.cpp") test_names = [(pytest.param(test, - id=osp.basename(test))) for test in test_names] + id=test.name)) for test in test_names] return test_names @pytest.mark.parametrize("test", get_test_names()) -def test_cpp_client(test, build_type, link_type): +def test_cpp_client(test, bin_path, execute_cmd): + print(test) # Build the path to the test executable from the source file name # . keep only the last two parts of the path: (language, basename) - test = "/".join(test.split("/")[-2:]) - # . drop the file extension - test = ".".join(test.split(".")[:-1]) - # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" - cmd = [test] - print(f"\nRunning test: {osp.basename(test)}") + + basename = test.stem + language = test.parent.name + test = bin_path / language / "bin" / basename + cmd = [str(test)] + print(f"\nRunning test: {test.name}") execute_cmd(cmd) time.sleep(1) - -def execute_cmd(cmd_list): - """Execute a command """ - - # spawning the subprocess and connecting to its output - proc = Popen( - cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=TEST_PATH) - try: - out, err = proc.communicate(timeout=180) - if out: - print("OUTPUT:", out.decode("utf-8")) - if err: - print("ERROR:", err.decode("utf-8")) - assert(proc.returncode == 0) - except UnicodeDecodeError: - output, errs = proc.communicate() - print("ERROR:", errs.decode("utf-8")) - assert(False) - except TimeoutExpired: - proc.kill() - output, errs = proc.communicate() - print("TIMEOUT: test timed out after test timeout limit of 120 seconds") - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) - except Exception: - proc.kill() - output, errs = proc.communicate() - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) diff --git a/tests/cpp/unit-tests/CMakeLists.txt b/tests/cpp/unit-tests/CMakeLists.txt index 0b0d9c06..1ce865c2 100644 --- a/tests/cpp/unit-tests/CMakeLists.txt +++ b/tests/cpp/unit-tests/CMakeLists.txt @@ -35,15 +35,15 @@ enable_language(CXX) # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) find_package(smartredis) + # Identify source files to be built into the CPP Catch2 unit tests file(GLOB UNIT_TESTS CONFIGURE_DEPENDS ./*.cpp) # Build the CPP Catch2 unit tests add_executable(cpp_unit_tests ${UNIT_TESTS}) -target_link_libraries(cpp_unit_tests PRIVATE smartredis Threads::Threads) +target_link_libraries(cpp_unit_tests PRIVATE smartredis) target_include_directories(cpp_unit_tests PRIVATE ${smartredis_INCLUDE_DIR}) +install(TARGETS cpp_unit_tests) diff --git a/tests/cpp/unit-tests/test_unit_cpp_client.py b/tests/cpp/unit-tests/test_unit_cpp_client.py index 6a8f48c4..26e9660d 100644 --- a/tests/cpp/unit-tests/test_unit_cpp_client.py +++ b/tests/cpp/unit-tests/test_unit_cpp_client.py @@ -24,72 +24,20 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import pathlib import pytest from os import path as osp -from os import getcwd -from glob import glob -from subprocess import Popen, PIPE, TimeoutExpired import time RANKS = 1 -TEST_PATH = osp.dirname(osp.abspath(__file__)) +TEST_PATH = pathlib.Path(__file__).resolve().parent timeout_limit = 180 -def get_test_names(): - """Obtain test names by globbing for client_test - Add tests manually if necessary - """ - test_names = [osp.join(TEST_PATH, "cpp_unit_tests")] - test_names = [(pytest.param(test, - id=osp.basename(test))) for test in test_names] - return test_names - -@pytest.mark.parametrize("test", get_test_names()) -def test_unit_cpp_client(test, build_type, link_type): +def test_unit_cpp_client(bin_path, execute_cmd): # Build the path to the test executable from the source file name - # . keep only the last three parts of the path: (language, unit-tests, basename) - test = "/".join(test.split("/")[-3:]) - # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" - cmd = [test] - print(f"\nRunning test: {osp.basename(test)}") + test = bin_path / "cpp" / "bin" / "cpp_unit_tests" + cmd = [str(test)] + print(f"\nRunning test: {test.name}") execute_cmd(cmd) time.sleep(1) - -def execute_cmd(cmd_list): - """Execute a command """ - - # spawning the subprocess and connecting to its output - proc = Popen( - cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=TEST_PATH) - try: - out, err = proc.communicate(timeout=timeout_limit) - print("OUTPUT:", out.decode("utf-8") if out else "None") - print("ERROR:", err.decode("utf-8") if err else "None") - if (proc.returncode != 0): - print("Return code:", proc.returncode) - assert(proc.returncode == 0) - except UnicodeDecodeError: - output, errs = proc.communicate() - print("OUTPUT:", out) - print("ERROR:", errs) - assert(False) - except TimeoutExpired: - proc.kill() - output, errs = proc.communicate() - print(f"TIMEOUT: test timed out after test timeout limit of {timeout_limit} seconds") - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - print("OUTPUT:", out) - print("ERROR:", errs) - assert(False) - except AssertionError: - assert(False) - except Exception as e: - print(e) - proc.kill() - output, errs = proc.communicate() - print("OUTPUT:", out) - print("ERROR:", errs) - assert(False) diff --git a/tests/fortran/test_fortran_client.py b/tests/fortran/test_fortran_client.py index 82d4e504..130aa1db 100644 --- a/tests/fortran/test_fortran_client.py +++ b/tests/fortran/test_fortran_client.py @@ -24,32 +24,29 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import pathlib import pytest -from os import path as osp -from os import getcwd, environ -from glob import glob -from subprocess import Popen, PIPE, TimeoutExpired +from os import environ import time test_gpu = environ.get("SR_TEST_DEVICE","cpu").lower() == "gpu" RANKS = 1 -TEST_PATH = osp.dirname(osp.abspath(__file__)) +TEST_PATH = pathlib.parent(pathlib.Path(__file__).resolve()) def get_test_names(): """Obtain test names by globbing for client_test Add tests manually if necessary """ - glob_path = osp.join(TEST_PATH, "client_test*") - test_names = glob(glob_path) + glob_path = TEST_PATH + test_names = glob_path.glob("client_test*.F90") test_names = list(filter(lambda test: test.find('gpu') == -1, test_names)) test_names = [(pytest.param(test, - id=osp.basename(test))) for test in test_names] + id=test.basename())) for test in test_names] return test_names - @pytest.mark.parametrize("test", get_test_names()) -def test_fortran_client(test, build_type, link_type): +def test_fortran_client(test, bin_path, execute_cmd): """This function actually runs the tests using the parameterization function provided in Pytest @@ -62,44 +59,13 @@ def test_fortran_client(test, build_type, link_type): # . drop the file extension test = ".".join(test.split(".")[:-1]) # . prepend the path to the built test executable - test = f"{getcwd()}/build/{build_type}/tests/{link_type}/{test}" + test = bin_path / test cmd = [test] - print(f"Running test: {osp.basename(test)}") + print(f"Running test: {test.name}") print(f"Test command {' '.join(cmd)}") execute_cmd(cmd) time.sleep(1) -def execute_cmd(cmd_list): - """Execute a command """ - - # spawning the subprocess and connecting to its output - proc = Popen( - cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=TEST_PATH) - try: - out, err = proc.communicate(timeout=120) - if out: - print("OUTPUT:", out.decode("utf-8")) - if err: - print("ERROR:", err.decode("utf-8")) - assert(proc.returncode == 0) - except UnicodeDecodeError: - output, errs = proc.communicate() - print("ERROR:", errs.decode("utf-8")) - assert(False) - except TimeoutExpired: - proc.kill() - output, errs = proc.communicate() - print("TIMEOUT: test timed out after test timeout limit of 120 seconds") - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) - except Exception: - proc.kill() - output, errs = proc.communicate() - print("OUTPUT:", output.decode("utf-8")) - print("ERROR:", errs.decode("utf-8")) - assert(False) - @pytest.mark.skipif( not test_gpu, reason="SR_TEST_DEVICE does not specify 'gpu'" @@ -109,6 +75,6 @@ def test_client_multigpu_mnist(): Test setting and running a machine learning model via the Fortran client on an orchestrator with multiple GPUs """ - tester_path = osp.join(TEST_PATH, "client_test_mnist_multigpu.F90") + tester_path = TEST_PATH / "client_test_mnist_multigpu.F90" test_fortran_client(tester_path) From ba5dd0a4376565497fb7a54e7406938f71322b31 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 25 Jun 2024 06:18:25 -0700 Subject: [PATCH 17/25] Fix test running directories --- conftest.py | 8 ++++---- tests/c/CMakeLists.txt | 3 +-- tests/cpp/test_cpp_client.py | 2 +- tests/cpp/unit-tests/test_unit_cpp_client.py | 2 +- tests/fortran/test_fortran_client.py | 20 ++++++++------------ 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/conftest.py b/conftest.py index 66efc193..1e180d4d 100644 --- a/conftest.py +++ b/conftest.py @@ -158,20 +158,20 @@ def bin_path(request): def execute_cmd(): def _execute_cmd(cmd_list, run_path=pathlib.Path.cwd()): """Execute a command """ - + print(f"Running {cmd_list} at {run_path}") # spawning the subprocess and connecting to its output proc = Popen( cmd_list, stderr=PIPE, stdout=PIPE, stdin=PIPE, cwd=run_path) try: out, err = proc.communicate(timeout=120) if out: - print("OUTPUT:", out.decode("utf-8")) + print("OUTPUT:", out.decode("unicode_escape")) if err: - print("ERROR:", err.decode("utf-8")) + print("ERROR:", err.decode("unicode_escape")) assert(proc.returncode == 0) except UnicodeDecodeError: output, errs = proc.communicate() - print("ERROR:", errs.decode("utf-8")) + print("ERROR:", errs.decode("unicode_escape")) assert(False) except TimeoutExpired: proc.kill() diff --git a/tests/c/CMakeLists.txt b/tests/c/CMakeLists.txt index f678af5d..32d8fcc3 100644 --- a/tests/c/CMakeLists.txt +++ b/tests/c/CMakeLists.txt @@ -59,6 +59,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) smartredis ) target_include_directories(${EXECUTABLE}_c_test PRIVATE ${smartredis_INCLUDE_DIR}) - list(APPEND test-targets ${EXECUTABLE}) - install( ${EXECUTABLE_c_test}) + install(TARGETS ${EXECUTABLE}_c_test) endforeach() diff --git a/tests/cpp/test_cpp_client.py b/tests/cpp/test_cpp_client.py index f6661a52..5f84a588 100644 --- a/tests/cpp/test_cpp_client.py +++ b/tests/cpp/test_cpp_client.py @@ -56,5 +56,5 @@ def test_cpp_client(test, bin_path, execute_cmd): test = bin_path / language / "bin" / basename cmd = [str(test)] print(f"\nRunning test: {test.name}") - execute_cmd(cmd) + execute_cmd(cmd, str(test.parent.parent)) time.sleep(1) diff --git a/tests/cpp/unit-tests/test_unit_cpp_client.py b/tests/cpp/unit-tests/test_unit_cpp_client.py index 26e9660d..1ccb1056 100644 --- a/tests/cpp/unit-tests/test_unit_cpp_client.py +++ b/tests/cpp/unit-tests/test_unit_cpp_client.py @@ -39,5 +39,5 @@ def test_unit_cpp_client(bin_path, execute_cmd): test = bin_path / "cpp" / "bin" / "cpp_unit_tests" cmd = [str(test)] print(f"\nRunning test: {test.name}") - execute_cmd(cmd) + execute_cmd(cmd, str(test.parent)) time.sleep(1) diff --git a/tests/fortran/test_fortran_client.py b/tests/fortran/test_fortran_client.py index 130aa1db..b3b7681e 100644 --- a/tests/fortran/test_fortran_client.py +++ b/tests/fortran/test_fortran_client.py @@ -32,7 +32,7 @@ test_gpu = environ.get("SR_TEST_DEVICE","cpu").lower() == "gpu" RANKS = 1 -TEST_PATH = pathlib.parent(pathlib.Path(__file__).resolve()) +TEST_PATH = pathlib.Path(__file__).resolve().parent def get_test_names(): """Obtain test names by globbing for client_test @@ -40,9 +40,9 @@ def get_test_names(): """ glob_path = TEST_PATH test_names = glob_path.glob("client_test*.F90") - test_names = list(filter(lambda test: test.find('gpu') == -1, test_names)) + test_names = list(filter(lambda test: str(test).find('gpu') == -1, test_names)) test_names = [(pytest.param(test, - id=test.basename())) for test in test_names] + id=test.name)) for test in test_names] return test_names @pytest.mark.parametrize("test", get_test_names()) @@ -55,15 +55,11 @@ def test_fortran_client(test, bin_path, execute_cmd): """ # Build the path to the test executable from the source file name # . keep only the last three parts of the path: (language, basename) - test = "/".join(test.split("/")[-2:]) - # . drop the file extension - test = ".".join(test.split(".")[:-1]) - # . prepend the path to the built test executable - test = bin_path / test - cmd = [test] - print(f"Running test: {test.name}") - print(f"Test command {' '.join(cmd)}") - execute_cmd(cmd) + basename = test.stem + language = test.parent.name + test = bin_path / language / "bin" / basename + cmd = [str(test)] + execute_cmd(cmd, TEST_PATH) time.sleep(1) @pytest.mark.skipif( From cdef9ce4219000de7f7583a312bae7427be3429e Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 25 Jun 2024 13:29:29 +0000 Subject: [PATCH 18/25] Fix install locations in Github Actions --- .github/workflows/run_tests.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 7f8412a0..b5b6b1db 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -66,7 +66,7 @@ jobs: rai_v: [1.2.7] # versions of RedisAI py_v: ['3.9.x', '3.10.x', '3.11.x'] # versions of Python compiler: [nvhpc-23-11, intel-2024.0, gcc-11, gcc-12] # intel compiler, and versions of GNU compiler - link_type: [Static, Shared] + link_type: [static, shared] env: COMPILER: ${{ matrix.compiler }} # used when the compiler is gcc/gfortran LINK_TYPE: ${{ matrix.link_type }} @@ -177,18 +177,25 @@ jobs: - name: Build and install test dependencies run: | make test-deps + + - name: Build and install SmartRedis library + run: | + make test-lib INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ + BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE \ + echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/install/$LINK_TYPE/lib >> $GITHUB_ENV # Make sure the examples work - name: Run examples run: | - make test-examples BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE \ + make test-examples INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ + BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE \ SR_TEST_PORT=7000 SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ INSTALL_PREFIX=$PWD/install/$LINK_TYPE # Run the tests using various DB deployments - name: Run tests run: | - make test-verbose-with-coverage \ + make test-verbose-with-coverage INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ COV_FLAGS="--cov=./src/python/module/smartredis/ --cov-report=xml --cov-append" \ BUILD_FORTRAN=ON BUILD_PYTHON=ON SR_TEST_REDIS_MODE=All SR_TEST_PORT=7000 LINK_TYPE=$LINK_TYPE \ SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ From 77baa72c924e9b578186f17a7a2c8b707a437f34 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 25 Jun 2024 16:25:44 +0000 Subject: [PATCH 19/25] Disable pedantic --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0c2d488e..860a045f 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ lib-with-fortran: lib # help: test-lib - Build SmartRedis clients into a dynamic library with least permissive compiler settings .PHONY: test-lib -test-lib: PEDANTIC=ON +test-lib: PEDANTIC=OFF # Re-enable after warnings fixed test-lib: lib # help: test-lib-with-fortran - Build SmartRedis clients into a dynamic library with least permissive compiler settings From 30a7ff6b9e51936e55a352082c366a96ea3b6d5f Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Wed, 26 Jun 2024 15:51:46 +0000 Subject: [PATCH 20/25] fix errant continuation marker --- .github/workflows/run_tests.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index b5b6b1db..86464deb 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -66,7 +66,7 @@ jobs: rai_v: [1.2.7] # versions of RedisAI py_v: ['3.9.x', '3.10.x', '3.11.x'] # versions of Python compiler: [nvhpc-23-11, intel-2024.0, gcc-11, gcc-12] # intel compiler, and versions of GNU compiler - link_type: [static, shared] + link_type: [shared] env: COMPILER: ${{ matrix.compiler }} # used when the compiler is gcc/gfortran LINK_TYPE: ${{ matrix.link_type }} @@ -75,6 +75,7 @@ jobs: steps: # Maximize the space in this image - name: Maximize build space + if: false uses: easimon/maximize-build-space@master with: root-reserve-mb: 30720 @@ -177,11 +178,11 @@ jobs: - name: Build and install test dependencies run: | make test-deps - + - name: Build and install SmartRedis library run: | make test-lib INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ - BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE \ + BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/install/$LINK_TYPE/lib >> $GITHUB_ENV # Make sure the examples work @@ -189,8 +190,8 @@ jobs: run: | make test-examples INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE \ - SR_TEST_PORT=7000 SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ - INSTALL_PREFIX=$PWD/install/$LINK_TYPE + SR_TEST_PORT=7000 SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ + INSTALL_PREFIX=$PWD/install/$LINK_TYPE # Run the tests using various DB deployments - name: Run tests From 83a74d6ab272ece8d834fb6d18d1f8c55afa002e Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Wed, 26 Jun 2024 20:07:07 +0000 Subject: [PATCH 21/25] Update TEST_PATH definition --- examples/test_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/test_examples.py b/examples/test_examples.py index 19589cff..6feeb7f3 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -31,7 +31,7 @@ import time RANKS = 1 -TEST_PATH = pathlib.parent(pathlib.Path(__file__).resolve()) +TEST_PATH = pathlib.Path(__file__).resolve().parent def get_test_names(): """Obtain test names by globbing for client_test From e9032dbc9a3e2888a828e6546d8be7b8fe053be2 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Thu, 27 Jun 2024 23:19:53 +0000 Subject: [PATCH 22/25] Fix last errors with tests --- .github/workflows/run_tests.yml | 17 +++--- CMakeLists.txt | 23 +++----- Makefile | 52 +++++++++---------- .../Config.smartredis-fortran.cmake.in | 0 .../Config.smartredis.cmake.in | 0 cmake/EnableCoverage.cmake | 11 ++++ conftest.py | 5 ++ examples/CMakeLists.txt | 9 +++- examples/parallel/CMakeLists.txt | 11 +++- examples/parallel/cpp/CMakeLists.txt | 8 +++ examples/parallel/cpp/smartredis_mnist.cpp | 6 +-- examples/parallel/fortran/CMakeLists.txt | 8 +++ .../parallel/fortran/smartredis_mnist.F90 | 4 +- examples/serial/CMakeLists.txt | 11 +++- examples/serial/c/CMakeLists.txt | 8 +++ examples/serial/cpp/CMakeLists.txt | 8 +++ examples/serial/cpp/smartredis_mnist.cpp | 6 +-- examples/serial/cpp/smartredis_model.cpp | 6 +-- examples/serial/fortran/CMakeLists.txt | 8 +++ examples/test_examples.py | 31 ++++++----- tests/CMakeLists.txt | 7 +++ tests/c/CMakeLists.txt | 7 +++ tests/c/test_c_client.py | 17 +++--- tests/cpp/CMakeLists.txt | 7 +++ tests/cpp/unit-tests/CMakeLists.txt | 7 +++ tests/fortran/CMakeLists.txt | 10 +++- 26 files changed, 193 insertions(+), 94 deletions(-) rename Config.smartredis-fortran.cmake.in => cmake/Config.smartredis-fortran.cmake.in (100%) rename Config.smartredis.cmake.in => cmake/Config.smartredis.cmake.in (100%) create mode 100644 cmake/EnableCoverage.cmake diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 86464deb..258cb647 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -71,11 +71,9 @@ jobs: COMPILER: ${{ matrix.compiler }} # used when the compiler is gcc/gfortran LINK_TYPE: ${{ matrix.link_type }} - steps: # Maximize the space in this image - name: Maximize build space - if: false uses: easimon/maximize-build-space@master with: root-reserve-mb: 30720 @@ -172,6 +170,12 @@ jobs: if: contains(matrix.os, 'ubuntu') run: sudo apt-get -y install cmake + - name: Build and install SmartRedis library + run: | + make test-lib INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ + BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE + echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/install/$LINK_TYPE/lib >> $GITHUB_ENV + - name: Build SmartRedis python and install run: python -m pip install -e .[dev,xarray] @@ -179,12 +183,6 @@ jobs: run: | make test-deps - - name: Build and install SmartRedis library - run: | - make test-lib INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ - BUILD_FORTRAN=ON BUILD_PYTHON=ON LINK_TYPE=$LINK_TYPE - echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/install/$LINK_TYPE/lib >> $GITHUB_ENV - # Make sure the examples work - name: Run examples run: | @@ -199,8 +197,7 @@ jobs: make test-verbose-with-coverage INSTALL_PREFIX=$PWD/install/$LINK_TYPE \ COV_FLAGS="--cov=./src/python/module/smartredis/ --cov-report=xml --cov-append" \ BUILD_FORTRAN=ON BUILD_PYTHON=ON SR_TEST_REDIS_MODE=All SR_TEST_PORT=7000 LINK_TYPE=$LINK_TYPE \ - SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} \ - INSTALL_PREFIX=$PWD/install/$LINK_TYPE + SR_TEST_REDISAI_VER=v${{ matrix.rai_v }} # Process and upload code coverage (Python was collected during pytest) - name: Collect coverage from C/C++/Fortran testers diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c389eaf..0f1957e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,10 +48,11 @@ endif() ## Cmake Modules include(GNUInstallDirs) include(ExternalProject) -include(CMakePrintHelpers) if(BUILD_PYTHON) include(FetchContent) endif() +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") +include(EnableCoverage) ## Configure the remainder of the builder set(CMAKE_CXX_STANDARD 17) @@ -59,21 +60,15 @@ set(CMAKE_CXX_VISIBILITY_PRESET default) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads) -if(CMAKE_BUILD_TYPE STREQUAL Coverage) - set(CMAKE_BUILD_TYPE Debug) - if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU")) - add_compile_options(--coverage) - add_link_options(--coverage) - else() - message(WARNING "A coverage build was specified, but the CMAKE compiler is not GCC") - endif() -endif() - if (BUILD_FORTRAN) enable_language(Fortran) set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/include") endif() +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + ## Include external libraries ## Note: These ExternalProjects need to be installed into the ## SmartRedis install directory since there are variants of the @@ -107,7 +102,6 @@ set_target_properties(libhiredis PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${hiredis_source_dir} ) -cmake_print_variables(hiredis_source_dir) # Define redis++ as an external project ExternalProject_Add(redis++ GIT_REPOSITORY https://github.com/sewenew/redis-plus-plus.git @@ -222,7 +216,6 @@ set(FORTRAN_SRC include_directories(SYSTEM $) ## Build the main SmartRedis library -cmake_print_variables(BUILD_SHARED_LIBS) set(CLIENT_SRC ${C_CPP_SRC}) add_library(smartredis ${CLIENT_SRC}) add_dependencies(smartredis hiredis redis++) @@ -288,7 +281,7 @@ install(EXPORT smartredis-targets DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis ) include(CMakePackageConfigHelpers) -configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.smartredis.cmake.in +configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/Config.smartredis.cmake.in smartredisConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis ) @@ -325,7 +318,7 @@ if (BUILD_FORTRAN) FILE smartredis-fortran.cmake DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran ) - configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.smartredis-fortran.cmake.in + configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/Config.smartredis-fortran.cmake.in smartredis-fortranConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/smartredis-fortran ) diff --git a/Makefile b/Makefile index 860a045f..ea7552ab 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ CWD := $(shell pwd) # Build variables NPROC := $(shell nproc 2>/dev/null || python -c "import multiprocessing as mp; print (mp.cpu_count())" 2>/dev/null || echo 4) INSTALL_PREFIX := $(CWD)/install -TEST_PREFIX := $(CWD)/tests/ +TEST_PREFIX := $(CWD)/tests EXAMPLES_PREFIX := $(CWD)/examples/bin BUILD_FORTRAN := OFF BUILD_PYTHON := OFF @@ -134,7 +134,7 @@ test-lib: lib # help: test-lib-with-fortran - Build SmartRedis clients into a dynamic library with least permissive compiler settings .PHONY: test-lib-with-fortran -test-lib-with-fortran: PEDANTIC=ON +test-lib-with-fortran: PEDANTIC=off test-lib-with-fortran: lib-with-fortran # help: test-deps - Make SmartRedis testing dependencies @@ -150,7 +150,7 @@ test-deps-gpu: test-deps # help: build-tests - build all tests (C, C++, Fortran) .PHONY: build-tests -build-tests: test-lib +build-tests: test-lib-with-fortran build-tests: build-unit-test-cpp build-tests: build-test-cpp build-tests: build-test-c @@ -173,7 +173,7 @@ build-test-cpp: catch2 build-unit-test-cpp: test-lib build-unit-test-cpp: catch2 @cmake -S tests/cpp/unit-tests -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp/unit-tests \ - -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/cpp \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis @cmake --build build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/cpp/unit-tests -- -j $(NPROC) @@ -183,7 +183,7 @@ build-unit-test-cpp: catch2 .PHONY: build-test-c build-test-c: test-lib @cmake -S tests/c -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/c \ - -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/c @cmake --build build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/c -- -j $(NPROC) @@ -193,9 +193,9 @@ build-test-c: test-lib # help: build-test-fortran - build the Fortran tests .PHONY: build-test-fortran build-test-fortran: BUILD_FORTRAN=ON -build-test-fortran: test-lib +build-test-fortran: test-lib-with-fortran @cmake -S tests/fortran -B build/$(BUILD_TYPE)/tests/$(LINK_TYPE)/fortran \ - -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \ -DCMAKE_INSTALL_PREFIX=$(TEST_PREFIX)/fortran \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran @@ -206,7 +206,7 @@ build-test-fortran: test-lib # help: build-examples - build all examples (serial, parallel) .PHONY: build-examples build-examples: lib - @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE) -DBUILD_TYPE=$(BUILD_TYPE) \ + @cmake -S examples -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -DCMAKE_INSTALL_PREFIX=$(EXAMPLES_PREFIX) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ @@ -219,7 +219,7 @@ build-examples: lib .PHONY: build-example-serial build-example-serial: lib @cmake -S examples/serial -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/serial \ - -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -DCMAKE_INSTALL_PREFIX=$(EXAMPLES_PREFIX) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran @@ -230,7 +230,7 @@ build-example-serial: lib .PHONY: build-example-parallel build-example-parallel: lib @cmake -S examples/parallel -B build/$(BUILD_TYPE)/examples/$(LINK_TYPE)/parallel \ - -DBUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DBUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) -DBUILD_FORTRAN=$(BUILD_FORTRAN) \ -DCMAKE_INSTALL_PREFIX=$(EXAMPLES_PREFIX) \ -Dsmartredis_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis \ -Dsmartredis-fortran_DIR=$(INSTALL_PREFIX)/share/cmake/smartredis-fortran @@ -345,7 +345,7 @@ define run_smartredis_tests_with_standalone_server echo "Running standalone tests" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --bin-path $(TEST_PREFIX) --build-fortran $(BUILD_FORTRAN) $(1) ; \ + --bin-path $(2) --build-fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down standalone Redis server" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes 1 --stop && \ @@ -365,7 +365,7 @@ define run_smartredis_tests_with_clustered_server echo "Running clustered tests" && \ PYTHONFAULTHANDLER=1 python -s -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --bin-path $(TEST_PREFIX) --build-fortran $(BUILD_FORTRAN) $(1) ; \ + --bin-path $(2) --build-fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down clustered Redis server" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) \ @@ -388,7 +388,7 @@ define run_smartredis_tests_with_uds_server echo "Running standalone tests with Unix Domain Socket connection" && \ PYTHONFAULTHANDLER=1 python -m pytest $(SR_TEST_PYTEST_FLAGS) $(COV_FLAGS) \ $(SKIP_DOCKER) $(SKIP_PYTHON) $(SKIP_FORTRAN) \ - --bin-path $(TEST_PREFIX) --build-fortran $(BUILD_FORTRAN) $(1) ; \ + --bin-path $(2) --build-fortran $(BUILD_FORTRAN) $(1) ; \ (testresult=$$?; \ echo "Shutting down standalone Redis server with Unix Domain Socket support" && \ python utils/launch_redis.py --port $(SR_TEST_PORT) --nodes 1 \ @@ -403,16 +403,16 @@ endef define run_smartredis_tests_with_server $(if $(or $(filter $(SR_TEST_REDIS_MODE),Standalone), $(filter $(SR_TEST_REDIS_MODE),All)), - $(call run_smartredis_tests_with_standalone_server,$(1)) + $(call run_smartredis_tests_with_standalone_server,$(1),$(2)) ) $(if $(or $(filter $(SR_TEST_REDIS_MODE),Clustered), $(filter $(SR_TEST_REDIS_MODE),All)), - $(call run_smartredis_tests_with_clustered_server,$(1)) + $(call run_smartredis_tests_with_clustered_server,$(1),$(2)) ) $(if $(or $(filter $(SR_TEST_REDIS_MODE),UDS), $(filter $(SR_TEST_REDIS_MODE),All)), $(if $(filter-out $(shell uname -s),Darwin), - $(call run_smartredis_tests_with_uds_server,$(1)), + $(call run_smartredis_tests_with_uds_server,$(1),$(2)), @echo "Skipping: Unix Domain Socket is not supported on MacOS" ) ) @@ -424,7 +424,7 @@ test: test-deps test: build-tests test: SR_TEST_PYTEST_FLAGS := -vv test: - @$(call run_smartredis_tests_with_server,./tests) + @$(call run_smartredis_tests_with_server,./tests, $(TEST_PREFIX)) # help: test-verbose - Build and run all tests [verbosely] .PHONY: test-verbose @@ -432,7 +432,7 @@ test-verbose: test-deps test-verbose: build-tests test-verbose: SR_TEST_PYTEST_FLAGS := -vv -s test-verbose: - @$(call run_smartredis_tests_with_server,./tests) + @$(call run_smartredis_tests_with_server,./tests, $(TEST_PREFIX)) # help: test-verbose-with-coverage - Build and run all tests [verbose-with-coverage] .PHONY: test-verbose-with-coverage @@ -441,14 +441,14 @@ test-verbose-with-coverage: test-deps test-verbose-with-coverage: build-tests test-verbose-with-coverage: SR_TEST_PYTEST_FLAGS := -vv -s test-verbose-with-coverage: - @$(call run_smartredis_tests_with_server,./tests) + @$(call run_smartredis_tests_with_server,./tests, $(TEST_PREFIX)) # help: test-c - Build and run all C tests .PHONY: test-c test-c: build-test-c test-c: SR_TEST_PYTEST_FLAGS := -vv -s test-c: - @$(call run_smartredis_tests_with_server,./tests/c) + @$(call run_smartredis_tests_with_server,./tests/c, $(TEST_PREFIX)) # help: test-cpp - Build and run all C++ tests .PHONY: test-cpp @@ -456,14 +456,14 @@ test-cpp: build-test-cpp test-cpp: build-unit-test-cpp test-cpp: SR_TEST_PYTEST_FLAGS := -vv -s test-cpp: - @$(call run_smartredis_tests_with_server,./tests/cpp) + @$(call run_smartredis_tests_with_server,./tests/cpp, $(TEST_PREFIX)) # help: unit-test-cpp - Build and run unit tests for C++ .PHONY: unit-test-cpp unit-test-cpp: build-unit-test-cpp unit-test-cpp: SR_TEST_PYTEST_FLAGS := -vv -s unit-test-cpp: - @$(call run_smartredis_tests_with_server,./tests/cpp/unit-tests) + @$(call run_smartredis_tests_with_server,./tests/cpp/unit-tests, $(TEST_PREFIX)) # help: test-py - run python tests .PHONY: test-py @@ -472,7 +472,7 @@ test-py: BUILD_PYTHON := ON test-py: lib test-py: SR_TEST_PYTEST_FLAGS := -vv test-py: - @$(call run_smartredis_tests_with_server,./tests/python) + @$(call run_smartredis_tests_with_server,./tests/python, $(TEST_PREFIX)) # help: test-fortran - run fortran tests .PHONY: test-fortran @@ -480,7 +480,7 @@ test-fortran: BUILD_FORTRAN := ON test-fortran: build-test-fortran test-fortran: SR_TEST_PYTEST_FLAGS := -vv -s test-fortran: - @$(call run_smartredis_tests_with_server,./tests/fortran) + @$(call run_smartredis_tests_with_server,./tests/fortran, $(TEST_PREFIX)) # help: testpy-cov - run python tests with coverage .PHONY: testpy-cov @@ -489,7 +489,7 @@ testpy-cov: BUILD_PYTHON := ON testpy-cov: SR_TEST_PYTEST_FLAGS := -vv testpy-cov: COV_FLAGS := --cov=./src/python/module/smartredis/ testpy-cov: - @$(call run_smartredis_tests_with_server,./tests/python) + @$(call run_smartredis_tests_with_server,./tests/python, $(TEST_PREFIX)) # help: test-examples - Build and run all examples .PHONY: test-examples @@ -497,7 +497,7 @@ test-examples: test-deps test-examples: build-examples testpy-cov: SR_TEST_PYTEST_FLAGS := -vv -s test-examples: - @$(call run_smartredis_tests_with_server,./examples) + @$(call run_smartredis_tests_with_server,./examples,$(EXAMPLES_PREFIX)) ############################################################################ diff --git a/Config.smartredis-fortran.cmake.in b/cmake/Config.smartredis-fortran.cmake.in similarity index 100% rename from Config.smartredis-fortran.cmake.in rename to cmake/Config.smartredis-fortran.cmake.in diff --git a/Config.smartredis.cmake.in b/cmake/Config.smartredis.cmake.in similarity index 100% rename from Config.smartredis.cmake.in rename to cmake/Config.smartredis.cmake.in diff --git a/cmake/EnableCoverage.cmake b/cmake/EnableCoverage.cmake new file mode 100644 index 00000000..ed6eeb19 --- /dev/null +++ b/cmake/EnableCoverage.cmake @@ -0,0 +1,11 @@ +function(enable_coverage) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU")) + set(CMAKE_BUILD_TYPE Debug) + add_compile_options(--coverage) + add_link_options(--coverage) + link_libraries(gcov) + message(WARNING "Enabling coverage with debug") + else() + message(WARNING "A coverage build was specified, but the CMAKE compiler is not GCC") + endif() +endfunction() \ No newline at end of file diff --git a/conftest.py b/conftest.py index 1e180d4d..46019523 100644 --- a/conftest.py +++ b/conftest.py @@ -154,6 +154,11 @@ def pytest_addoption(parser): def bin_path(request): return pathlib.Path(request.config.getoption("--bin-path")) +# Fixture to retrieve the build type setting +@pytest.fixture(scope="module") +def build_fortran(request): + return pathlib.Path(request.config.getoption("--build-fortran")) + @pytest.fixture() def execute_cmd(): def _execute_cmd(cmd_list, run_path=pathlib.Path.cwd()): diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a314dd7d..ca2d5f96 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -28,10 +28,17 @@ cmake_minimum_required(VERSION 3.13) project(SmartRedis-Examples) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Enable language support for the examples enable_language(C) enable_language(CXX) -if (SR_FORTRAN) +if (BUILD_FORTRAN) enable_language(Fortran) endif() diff --git a/examples/parallel/CMakeLists.txt b/examples/parallel/CMakeLists.txt index ae544d06..c570c29e 100644 --- a/examples/parallel/CMakeLists.txt +++ b/examples/parallel/CMakeLists.txt @@ -30,12 +30,19 @@ project(SmartRedis-Examples-Parallel) # Enable language support for the examples enable_language(CXX) -if (SR_FORTRAN) +if (BUILD_FORTRAN) enable_language(Fortran) endif() +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Bring in subdirectories add_subdirectory(cpp) -if (SR_FORTRAN) +if (BUILD_FORTRAN) add_subdirectory(fortran) endif() diff --git a/examples/parallel/cpp/CMakeLists.txt b/examples/parallel/cpp/CMakeLists.txt index 4a70fb0c..3d5b3e02 100644 --- a/examples/parallel/cpp/CMakeLists.txt +++ b/examples/parallel/cpp/CMakeLists.txt @@ -31,6 +31,13 @@ project(SmartRedis-Examples-Parallel-Cpp) # Enable language support for the examples enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) # Locate dependencies @@ -55,4 +62,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) MPI::MPI_CXX smartredis ) + install(TARGETS ${EXECUTABLE}_cpp_parallel RUNTIME DESTINATION parallel/cpp) endforeach() diff --git a/examples/parallel/cpp/smartredis_mnist.cpp b/examples/parallel/cpp/smartredis_mnist.cpp index 4b28b004..c0021e61 100644 --- a/examples/parallel/cpp/smartredis_mnist.cpp +++ b/examples/parallel/cpp/smartredis_mnist.cpp @@ -43,7 +43,7 @@ void run_mnist(const std::string& model_name, // Load the mnist image from a file using MPI rank 0 if (rank == 0) { - std::string image_file = "../../common/mnist_data/one.raw"; + std::string image_file = "mnist_data/one.raw"; std::ifstream fin(image_file, std::ios::binary); std::ostringstream ostream; ostream << fin.rdbuf(); @@ -112,14 +112,14 @@ int main(int argc, char* argv[]) { // Build model key, file name, and then set model // from file using client API std::string model_key = "mnist_model"; - std::string model_file = "../../common/mnist_data/mnist_cnn.pt"; + std::string model_file = "mnist_data/mnist_cnn.pt"; client.set_model_from_file(model_key, model_file, "TORCH", "CPU", 20); // Build script key, file name, and then set script // from file using client API std::string script_key = "mnist_script"; - std::string script_file = "../../common/mnist_data/data_processing_script.txt"; + std::string script_file = "mnist_data/data_processing_script.txt"; client.set_script_from_file(script_key, "CPU", script_file); // Get model and script to illustrate client API diff --git a/examples/parallel/fortran/CMakeLists.txt b/examples/parallel/fortran/CMakeLists.txt index 9701247f..df227156 100644 --- a/examples/parallel/fortran/CMakeLists.txt +++ b/examples/parallel/fortran/CMakeLists.txt @@ -32,6 +32,13 @@ project(SmartRedis-Examples-Parallel-Fortran) enable_language(Fortran) enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) find_package(MPI REQUIRED) @@ -66,4 +73,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) smartredis smartredis-fortran ) + install(TARGETS ${EXECUTABLE}_fortran_parallel RUNTIME DESTINATION parallel/fortran) endforeach() diff --git a/examples/parallel/fortran/smartredis_mnist.F90 b/examples/parallel/fortran/smartredis_mnist.F90 index aaa287bb..b2fb3231 100644 --- a/examples/parallel/fortran/smartredis_mnist.F90 +++ b/examples/parallel/fortran/smartredis_mnist.F90 @@ -35,9 +35,9 @@ program mnist_example #include "enum_fortran.inc" character(len=*), parameter :: model_key = "mnist_model" - character(len=*), parameter :: model_file = "../../common/mnist_data/mnist_cnn.pt" + character(len=*), parameter :: model_file = "mnist_data/mnist_cnn.pt" character(len=*), parameter :: script_key = "mnist_script" - character(len=*), parameter :: script_file = "../../common/mnist_data/data_processing_script.txt" + character(len=*), parameter :: script_file = "mnist_data/data_processing_script.txt" type(client_type) :: client integer :: err_code, pe_id, result diff --git a/examples/serial/CMakeLists.txt b/examples/serial/CMakeLists.txt index 82690cb7..0efb7c30 100644 --- a/examples/serial/CMakeLists.txt +++ b/examples/serial/CMakeLists.txt @@ -28,16 +28,23 @@ cmake_minimum_required(VERSION 3.13) project(SmartRedis-Examples-Serial) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Enable language support for the examples enable_language(C) enable_language(CXX) -if (SR_FORTRAN) +if (BUILD_FORTRAN) enable_language(Fortran) endif() # Bring in subdirectories add_subdirectory(c) add_subdirectory(cpp) -if (SR_FORTRAN) +if (BUILD_FORTRAN) add_subdirectory(fortran) endif() diff --git a/examples/serial/c/CMakeLists.txt b/examples/serial/c/CMakeLists.txt index d2fcaa6b..82af2eb5 100644 --- a/examples/serial/c/CMakeLists.txt +++ b/examples/serial/c/CMakeLists.txt @@ -32,6 +32,13 @@ project(SmartRedis-Examples-Serial-C) enable_language(C) enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) @@ -55,4 +62,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) target_link_libraries(${EXECUTABLE}_c_serial smartredis ) + install(TARGETS ${EXECUTABLE}_c_serial RUNTIME DESTINATION serial/c) endforeach() diff --git a/examples/serial/cpp/CMakeLists.txt b/examples/serial/cpp/CMakeLists.txt index 70c802eb..89ce0b65 100644 --- a/examples/serial/cpp/CMakeLists.txt +++ b/examples/serial/cpp/CMakeLists.txt @@ -31,6 +31,13 @@ project(SmartRedis-Examples-Serial-Cpp) # Enable language support for the examples enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) @@ -56,4 +63,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) target_link_libraries(${EXECUTABLE}_cpp_serial smartredis ) + install(TARGETS ${EXECUTABLE}_cpp_serial RUNTIME DESTINATION serial/cpp) endforeach() diff --git a/examples/serial/cpp/smartredis_mnist.cpp b/examples/serial/cpp/smartredis_mnist.cpp index 1e039cdc..620e16a7 100644 --- a/examples/serial/cpp/smartredis_mnist.cpp +++ b/examples/serial/cpp/smartredis_mnist.cpp @@ -37,7 +37,7 @@ void run_mnist(const std::string& model_name, std::vector img(n_values, 0); // Load the MNIST image from a file - std::string image_file = "../../common/mnist_data/one.raw"; + std::string image_file = "mnist_data/one.raw"; std::ifstream fin(image_file, std::ios::binary); std::ostringstream ostream; ostream << fin.rdbuf(); @@ -80,14 +80,14 @@ int main(int argc, char* argv[]) { // Build model key, file name, and then set model // from file using client API std::string model_key = "mnist_model"; - std::string model_file = "../../common/mnist_data/mnist_cnn.pt"; + std::string model_file = "mnist_data/mnist_cnn.pt"; client.set_model_from_file( model_key, model_file, "TORCH", "CPU", 20); // Build script key, file name, and then set script // from file using client API std::string script_key = "mnist_script"; - std::string script_file = "../../common/mnist_data/data_processing_script.txt"; + std::string script_file = "mnist_data/data_processing_script.txt"; client.set_script_from_file(script_key, "CPU", script_file); // Get model and script to illustrate client API diff --git a/examples/serial/cpp/smartredis_model.cpp b/examples/serial/cpp/smartredis_model.cpp index 10d9a409..26d2e59a 100644 --- a/examples/serial/cpp/smartredis_model.cpp +++ b/examples/serial/cpp/smartredis_model.cpp @@ -37,7 +37,7 @@ int main(int argc, char* argv[]) { std::vector img(n_values, 0); // Load the mnist image from a file - std::string image_file = "../../common/mnist_data/one.raw"; + std::string image_file = "mnist_data/one.raw"; std::ifstream fin(image_file, std::ios::binary); std::ostringstream ostream; ostream << fin.rdbuf(); @@ -51,12 +51,12 @@ int main(int argc, char* argv[]) { // Use the client to set a model in the database from a file std::string model_key = "mnist_model"; - std::string model_file = "../../common/mnist_data/mnist_cnn.pt"; + std::string model_file = "mnist_data/mnist_cnn.pt"; client.set_model_from_file(model_key, model_file, "TORCH", "CPU", 20); // Use the client to set a script from the database form a file std::string script_key = "mnist_script"; - std::string script_file = "../../common/mnist_data/data_processing_script.txt"; + std::string script_file = "mnist_data/data_processing_script.txt"; client.set_script_from_file(script_key, "CPU", script_file); // Declare keys that we will use in forthcoming client commands diff --git a/examples/serial/fortran/CMakeLists.txt b/examples/serial/fortran/CMakeLists.txt index 4c78583e..f1ceed5b 100644 --- a/examples/serial/fortran/CMakeLists.txt +++ b/examples/serial/fortran/CMakeLists.txt @@ -32,6 +32,13 @@ project(SmartRedis-Examples-Serial-Fortran) enable_language(Fortran) enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) @@ -57,4 +64,5 @@ foreach(EXECUTABLE ${EXECUTABLES}) smartredis smartredis-fortran ) + install(TARGETS ${EXECUTABLE}_fortran_serial RUNTIME DESTINATION serial/fortran) endforeach() diff --git a/examples/test_examples.py b/examples/test_examples.py index 6feeb7f3..26dfd1e3 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -25,13 +25,12 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import pytest -from os import path as osp from glob import glob import pathlib import time RANKS = 1 -TEST_PATH = pathlib.Path(__file__).resolve().parent +TEST_PATH = pathlib.Path(__file__).resolve().parent # Should be the smartredis/examples directory def get_test_names(): """Obtain test names by globbing for client_test @@ -40,28 +39,28 @@ def get_test_names(): glob_path_1 = TEST_PATH.glob("*/*/example*") glob_path_2 = TEST_PATH.glob("*/*/smartredis*") test_names = list(glob_path_1) + list(glob_path_2) - test_names = list(filter(lambda test: test.find('example_utils') == -1, test_names)) - test_names = list(filter(lambda test: test.find('.py') == -1, test_names)) + test_names = list(filter(lambda test: str(test).find('example_utils') == -1, test_names)) + test_names = list(filter(lambda test: str(test).find('.py') == -1, test_names)) test_names = [(pytest.param(test, - id=osp.basename(test))) for test in test_names] + id=test.name)) for test in test_names] return test_names @pytest.mark.parametrize("test", get_test_names()) def test_example(test, bin_path, build_fortran, execute_cmd): - if (build_fortran == "ON" or ".F90" not in test): + if (build_fortran or ".F90" not in str(test)): # Build the path to the test executable from the source file name # . keep only the last three parts of the path: (parallel/serial, language, basename) - test = "/".join(test.split("/")[-3:]) - test_subdir = "/".join(test.split("/")[0:2]) - # . drop the file extension - test = ".".join(test.split(".")[:-1]) - # . prepend the path to the built test executable - test = bin_path / test - cmd = ["mpirun", "-n", "2"] if "parallel" in test else [] - cmd += [test] - print(f"\nRunning test: {test.basename()}") + + basename = test.stem + language = test.parent.name + execution = test.parent.parent.name + test = bin_path/execution/language/basename + + cmd = ["mpirun", "-n", "2"] if "parallel" in str(test) else [] + cmd += [str(test)] + print(f"\nRunning test: {test.name}") print(f"Test command {' '.join(cmd)}") - execute_cmd(cmd, pathlib.Path.cwd()/test_subdir) + execute_cmd(cmd, str(TEST_PATH/"common")) time.sleep(1) else: print (f"Skipping Fortran test {test}") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7e8eb6bc..718689f0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,6 +35,13 @@ if (BUILD_FORTRAN) enable_language(Fortran) endif() +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Bring in subdirectories add_subdirectory(c) add_subdirectory(cpp) diff --git a/tests/c/CMakeLists.txt b/tests/c/CMakeLists.txt index 32d8fcc3..0cb28cec 100644 --- a/tests/c/CMakeLists.txt +++ b/tests/c/CMakeLists.txt @@ -31,6 +31,13 @@ project(SmartSim-Tests-C) # Enable language support for the tests enable_language(C) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) diff --git a/tests/c/test_c_client.py b/tests/c/test_c_client.py index 8c35fef9..8efae5e7 100644 --- a/tests/c/test_c_client.py +++ b/tests/c/test_c_client.py @@ -51,13 +51,10 @@ def test_c_client(test, bin_path, execute_cmd): :type test: str """ # Build the path to the test executable from the source file name - # . keep only the last two parts of the path: (language, basename) - test = "/".join(test.split("/")[-2:]) - # . drop the file extension - test = ".".join(test.split(".")[:-1]) - # . prepend the path to the built test executable - test = bin_path / test - cmd = [test] - print(f"\nRunning test: {test.basename()}") - execute_cmd(cmd) - time.sleep(1) + basename = test.stem + language = test.parent.name + test = bin_path / language / "bin" / basename + cmd = [str(test)] + print(f"\nRunning test: {test.name}") + execute_cmd(cmd, str(test.parent.parent)) + time.sleep(1) \ No newline at end of file diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index 0d9bfc21..1b49008d 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -31,6 +31,13 @@ project(SmartSim-Tests-Cpp) # Enable language support for the tests enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) diff --git a/tests/cpp/unit-tests/CMakeLists.txt b/tests/cpp/unit-tests/CMakeLists.txt index 1ce865c2..eedca8a2 100644 --- a/tests/cpp/unit-tests/CMakeLists.txt +++ b/tests/cpp/unit-tests/CMakeLists.txt @@ -32,6 +32,13 @@ project(SmartSim-Tests-Cpp-UnitTests) # Enable language support for the tests enable_language(CXX) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) diff --git a/tests/fortran/CMakeLists.txt b/tests/fortran/CMakeLists.txt index c80e6a0a..4d5f7230 100644 --- a/tests/fortran/CMakeLists.txt +++ b/tests/fortran/CMakeLists.txt @@ -31,6 +31,13 @@ project(SmartRedis-Tests-Fortran) # Enable language support for the tests enable_language(Fortran) +# Add our custom module(s) stored in smartredis/cmake +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../cmake") +include(EnableCoverage) +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + enable_coverage() +endif() + # Configure the build set(CMAKE_CXX_STANDARD 17) SET(CMAKE_C_STANDARD 99) @@ -68,7 +75,8 @@ foreach(EXECUTABLE ${EXECUTABLES}) OUTPUT_NAME ${EXECUTABLE} ) target_link_libraries(${EXECUTABLE}_fortran_test - smartredis smartredis-fortran test-utils Threads::Threads + smartredis smartredis-fortran test-utils ) target_include_directories(${EXECUTABLE}_fortran_test PRIVATE ${smartredis_INCLUDE_DIR} ${smartredis-fortran_INCLUDE_DIR}) + install(TARGETS ${EXECUTABLE}_fortran_test) endforeach() \ No newline at end of file From ecbc59c2ce952a44d8cbfef285dabc06d07734b2 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Fri, 28 Jun 2024 23:28:10 +0000 Subject: [PATCH 23/25] Final changes --- .github/workflows/run_tests.yml | 2 +- CMakeLists.txt | 6 + doc/changelog.md | 34 ++++- doc/install/lib.rst | 239 ++++++++++++++++++++------------ 4 files changed, 189 insertions(+), 92 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 258cb647..790cdf71 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -66,7 +66,7 @@ jobs: rai_v: [1.2.7] # versions of RedisAI py_v: ['3.9.x', '3.10.x', '3.11.x'] # versions of Python compiler: [nvhpc-23-11, intel-2024.0, gcc-11, gcc-12] # intel compiler, and versions of GNU compiler - link_type: [shared] + link_type: [shared, static] env: COMPILER: ${{ matrix.compiler }} # used when the compiler is gcc/gfortran LINK_TYPE: ${{ matrix.link_type }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f1957e6..312f916c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ option(BUILD_FORTRAN "Build the fortran client library" OFF) option(BUILD_PYTHON "Build the python module" OFF) option(BUILD_SHARED_LIBS "Build using shared libraries" ON) option(PEDANTIC "Build with strictest compiler settings" OFF) +option(RETAIN_RPATH "Keep the path of the linked main SmartRedis library. Only applies to shared library builds" ON) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install) endif() @@ -306,6 +307,11 @@ if (BUILD_FORTRAN) target_include_directories(smartredis PUBLIC $ ) + if(RETAIN_RPATH) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + endif() + install( TARGETS smartredis-fortran EXPORT smartredis-fortran-targets diff --git a/doc/changelog.md b/doc/changelog.md index 3575a101..e0aee20f 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -6,7 +6,16 @@ Released on 14 May 2024 Description +<<<<<<< HEAD - Remove broken oss.redis.com URLs from documentation +======= +- Add option to allow SmartRedis Fortran library to retain the + path to the main client library +- Update examples and tests to use find_package(smartredis) +- Generate config files necessary to allow CMake projects to add + SmartRedis via find_package +- Allow users to specify install location of SmartRedis libraries +>>>>>>> 783e335 (Final changes) - Streamline compilation of SmartRedis dependencies - Pin NumPy version to 1.x - Improve client error logging @@ -33,10 +42,33 @@ Description Detailed Notes +- As part of this cleanup, some behaviors of how the libraries were + named have been removed. The testing suite now distinguishes between + various build types (e.g. Debug, Coverage, etc.) by specifying the + ``CMAKE_INSTALL_PREFIX`` instead of appending it as part of the name + of the library itself. + ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) +- The SmartRedis Fortran library now by default will retain the path + to the SmartRedis C/C++ library. This should avoid occasional problems + where users were getting "library not found" errors if they had moved + libraries post-installation + ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) +- All the examples and tests now use the ``find_package`` functionality + to setup linking flags + ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) +- The install process now generates package configuration files for + the C/C++ SmartRedis library and the Fortran SmartRedis library. + Users can use the ``find_package()`` command in their CMakeLists.txt + to setup the linking and include flags automatically + ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) +- The CMakeLists.txt for SmartRedis now includes the install commands + which allow users to specify the specific install prefix to install + the SmartRedis libraries, header files, and Fortran .mod files + ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) - hiredis, redis++, and pybind are now retrieved and installed in `CMakeLists.txt` instead of in the Makefile. This decouples the user-facing side of SmartRedis from the Makefile, which now can be - used as a convenient interface to compile SmartRedis with various + used pureley as a convenient interface to compile SmartRedis with various options and coordinate testing ([PR497](https://github.com/CrayLabs/SmartRedis/pull/497)) - The new major version release of Numpy is incompatible with modules diff --git a/doc/install/lib.rst b/doc/install/lib.rst index b8ad41ad..3b20b074 100644 --- a/doc/install/lib.rst +++ b/doc/install/lib.rst @@ -1,32 +1,107 @@ +For C, C++, and Fortran applications, the SmartRedis client library will need +to be compiled and linked in. The build system is CMake-based but we also +offer a Makefile that cover the requirements for most users. -Clone the SmartRedis repository and optionally checkout a specific branch or tag: +Downloading SmartRedis via the Github release page is possible, however we recommend +that most users clone the repository via git .. code-block:: bash git clone https://github.com/CrayLabs/SmartRedis.git [--branch tag_name] smartredis -The release tarball can also be used instead of cloning the git repository, but -the preferred method is a repository clone. + +CMake-based build +----------------- + +The ``CMakeLists.txt`` file in the SmartRedis root directory is fully self contained +and can be used directly to compile and install the SmartRedis library. At a bare +minimum users, can compile the library with + +.. code-block:: bash + + cd /path/to/SmartRedis + mkdir build + cd build + cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install/ + make install -j + +which will compile the C and C++ interfaces to SmartRedis and install the libraries +and all header files to ``/path/to/install/location``. + +For other CMake-based projects, the config files for SmartRedis will be in the +`share/cmake/smartredis` subdirectory and can be included by modifying the +application's ``CMakeLists.txt`` + +.. code-block:: cmake + + find_package(smartredis REQUIRED) + target_link_libraries(example_target smartredis) + target_include_directories(example_target ${smartredis_INCLUDE_DIR}) + +For more advanced used we provide the following options, their default settings, +and the allowed values which can be set at configuration time via +``-DEXAMPLE_PARAMETER=EXAMPLE_VALUE`` + +.. list-table:: SmartRedis CMake options + :widths: 25 10 25 50 + :header-rows: 1 + + * - Parameter name + - Default + - Allowed values + - Description + * - BUILD_FORTRAN + - OFF + - ON, OFF + - Build the Fortran client library in addition to C/C++ + * - BUILD_PYTHON + - OFF + - ON, OFF + - Build the Python client in addition to C/C++ (useful if the SmartRedis + python package was installed in editable mode) + * - BUILD_SHARED_LIBS + - ON + - ON, OFF + - If ``ON``, build SmartRedis libraries as a dynamic library, otherwise + as a static library + * - CMAKE_BUILD_TYPE + - Release + - Release, Debug, Coverage + - Determine whether the optimized, debuggable, or debuggable with coverage + version of SmartRedis will be compiled + * - CMAKE_INSTALL_PREFIX + - ``/usr/local`` + - Any path + - Install path prefix, prepended onto install directories. + * - PEDANTIC + - OFF + - ON, OFF + - If ON, error out if any compiler warnings are found + * - RETAIN_RPATH + - ON + - ON, OFF + - If ON, retain the path to the libsmartredis library for the Fortran library + when using dynamic linking + + +Makefile-based build +-------------------- The ```Makefile`` included in the top level of the SmartRedis repository has two main targets: ``lib`` which will create a dynamic library for C, C++, and (optionally) Fortran and Python clients; and ``lib-with-fortran`` which will also -unconditionally build a library for Fortran applications. ``make help`` will list -additional targets that are used for SmartRedis development. +build a library for Fortran applications. ``make help`` will list additional +targets that are used for SmartRedis development. .. code-block:: bash cd SmartRedis make lib #or lib-with-fortran -The SmartRedis library will be installed in ``SmartRedis/install/lib/`` and the +By default, the SmartRedis library will be compiled as a shared library with the +system default compilers and installed in ``SmartRedis/install/lib/`` and the SmartRedis header files (and optionally the Fortran ``.mod`` files) will be -installed in ``SmartRedis/install/include/``. The library installation can be -used to easily include SmartRedis capabilities in C++, C, and Fortran -applications. - -The above command will build SmartRedis with the system's default compilers. To -specify a specific compler users can set the ``CC``, ``CXX``, and ``FC`` variables. +installed in ``SmartRedis/install/include/``. .. code-block:: bash @@ -37,7 +112,7 @@ For reference, the appropriate values for ``CC``, ``CXX``, and ``FC`` for the co chains we support are: .. list-table:: Values for compiler chains - :widths: 20 12 12 12 + :widths: 20 12 12 12 :header-rows: 1 * - Compiler Chain @@ -61,21 +136,14 @@ chains we support are: - ``nvc++`` - ``nvfortran`` - -Customizing the library build ------------------------------ - By default, the SmartRedis library is built as a shared library. For some applications, however, it is preferable to link to a statically compiled -library. This can be done easily with the command: +library. This can be done by specifying the ``LINK_TYPE`` .. code-block:: bash - cd SmartRedis - # Static build - make lib SR_LINK=Static - # Shared build - make lib SR_LINK=Shared #or skip the SR_LINK variable as this is the default + make lib LINK_TYPE=shared # Default shared + make lib LINK_TYPE=static # Static build Linked statically, the SmartRedis library will have a ``.a`` file extension. When linked dynamically, the SmartRedis library will have a ``.so`` file extension. @@ -91,17 +159,11 @@ via a variable supplied to make: cd SmartRedis # Release build - make lib SR_BUILD=Release #or skip the SR_BUILD variable as this is the default + make lib BUILD_TYPE=Release # Default # Debug build - make lib SR_BUILD=Debug + make lib BUILD_TYPE=Debug # Code coverage build - make lib SR_BUILD=Coverage - -The name of the library produced for a Debug mode build is ``smartredis-debug``. -The name of the library produced for a Coverage mode build is ``smartredis-coverage``. -The name of the library produced for a Release mode build is ``smartredis``. -In each case, the file extension is dependent on the link type, ``.so`` or ``.a``. -All libraries will be located in the ``install/lib`` folder. + make lib BUILD_TYPE=Coverage Finally, it is possible to build SmartRedis to include Python and/or Fortran support (both are omitted by default): @@ -110,30 +172,27 @@ Finally, it is possible to build SmartRedis to include Python and/or Fortran sup cd SmartRedis # Build support for Python - make lib SR_PYTHON=ON + make lib BUILD_PYTHON=ON # Build support for Fortran - make lib SR_FORTRAN=ON # equivalent to make lib-with-fortran + make lib BUILD_FORTRAN=ON # equivalent to make lib-with-fortran # Build support for Python and Fortran - make lib SR_PYTHON=ON SR_FORTRAN=ON # or make lib-with-fortran SR_PYTHON=ON + make lib BUILD_PYTHON=ON BUILD_FORTRAN=ON # or make lib-with-fortran BUILD_PYTHON=ON -The build mode, link type, and Fortran/Python support settings are fully orthogonal; -any combination of them is supported. For example, a statically linked debug build -with Python support may be achieved via the following command: +Any combination of the build mode, link type, and Fortran/Python support +settings is supported For example, a statically linked debug build with Python +support may be achieved via the following command: .. code-block:: bash cd SmartRedis - make lib SR_LINK=Static SR_BUILD=Debug SR_PYTHON=ON + make lib LINK_TYPE=Static BUILD_TYPE=Debug BUILD_PYTHON=ON -The SR_LINK, SR_BUILD, SR_PYTHON, and SR_FORTRAN variables are fully supported for all +The LINK_TYPE, BUILD_TYPE, BUILD_PYTHON, and BUILD_FORTRAN variables are fully supported for all test and build targets in the Makefile. -Fortran support is built in a secondary library. -The name of the Fortran library produced for a Debug mode build is ``smartredis-fortran-debug``. -The name of the library produced for a Coverage mode build is ``smartredis-fortran-coverage``. -The name of the library produced for a Release mode build is ``smartredis-fortran``. -As with the main libray, the file extension is dependent on the link type, ``.so`` or ``.a``. -All libraries will be located in the ``install/lib`` folder. +Fortran support is built in a secondary library ``libsmartredis-fortran``. As +with the main library, the file extension is dependent on the link type, ``.so`` +or ``.a``. All libraries will be located in the ``install/lib`` folder. Additional make variables are described in the ``help`` make target: @@ -143,6 +202,44 @@ Additional make variables are described in the ``help`` make target: cd SmartRedis make help +Adding SmartRedis as a CMake ExternalProject +-------------------------------------------- + +Most applications should be able to incorporate the following into their +``CMakeLists.txt`` to + +.. code-block:: cmake + + include(ExternalProject) + ExternalProject_Add(smartredis + GIT_REPOSITORY https://github.com/CrayLabs/SmartRedis.git + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/external + -DBUILD_FORTRAN=on # For Fortran applications + PREFIX ${CMAKE_BINARY_DIR}/external + ) + ExternalProject_Get_Property(smartredis binary_dir source_dir) + + add_library(libsmartredis SHARED IMPORTED) + add_dependencies(libsmartredis smartredis) + set_target_properties(libsmartredis PROPERTIES + IMPORTED_LOCATION ${binary_dir}/libsmartredis.so + INTERFACE_INCLUDE_DIRECTORIES $ + + # Optional, only for Fortran applications + add_library(libsmartredis-fortran SHARED IMPORTED) + add_dependencies(libsmartredis-fortran smartredis) + set_target_properties(libsmartredis PROPERTIES + IMPORTED_LOCATION ${binary_dir}/libsmartredis-fortran.so + INTERFACE_INCLUDE_DIRECTORIES $ + + # ... define the example_target executable here + + target_include_directories(example_target PRIVATE ${CMAKE_BINARY_DIR}/external/include) + target_link_libraries(example_target libsmartredis) + # Optional, only for Fortran applcations + target_link_libraries(example_target libsmartredis-fortran) + + Linking instructions using compiler flags ----------------------------------------- @@ -155,7 +252,8 @@ following flags should be included for the preprocessor The linking flags will differ slightly whether the Fortran client library needs to be included. If so, be sure that you ran ``make lib-with-fortran`` (or ``make -lib SR_FORTRAN=ON``) and include the SmartRedis fortran library via the following flags: +lib BUILD_FORTRAN=ON``) and include the SmartRedis fortran library via the +following flags: .. code-block:: text @@ -165,48 +263,9 @@ lib SR_FORTRAN=ON``) and include the SmartRedis fortran library via the followin Fortran applications need to link in both ``smartredis-fortran`` and ``smartredis`` libraries whereas C/C++ applications require only - ``smartredis``. For debug or coverage builds, use the appropriate alternate - libraries as described previously. - - -Linking instructions for CMake-based build systems --------------------------------------------------- - -The CMake instructions below illustrate how to compile a C or C++ application -with SmartRedis. To build a Fortran client, uncomment out the lines after the -``Fortran-only`` comments - -.. code-block:: text + ``smartredis``. - cmake_minimum_required(VERSION 3.13) - project(Example) +.. warning:: - set(CMAKE_CXX_STANDARD 17) - - set(SMARTREDIS_INSTALL_PATH /path/to/smartredis/install) - find_library(SMARTREDIS_LIBRARY smartredis - PATHS ${SMARTREDIS_INSTALL_PATH}/lib - NO_DEFAULT_PATH REQUIRED - ) - - # Fortran-only: - #find_library(SMARTREDIS_FORTRAN_LIBRARY smartredis-fortran - # PATHS SMARTREDIS_INSTALL_PATH/lib - # NO_DEFAULT_PATH REQUIRED - #) - - include_directories(SYSTEM - /usr/local/include - ${SMARTREDIS_INSTALL_PATH}/include - ) - - # Build executables - - add_executable(example - example.cpp - ) - target_link_libraries(example - ${SMARTREDIS_LIBRARY} - # Fortran-only: - #${SMARTREDIS_FORTRAN_LIBRARY} - ) \ No newline at end of file + For static linking, due to limitations with CMake, users should also + add the following flags ``-lhiredis -lredis++`` to the link command \ No newline at end of file From 854199dca03b7ca8263c5318f6015ef48e53158b Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 2 Jul 2024 17:12:09 +0000 Subject: [PATCH 24/25] Add hint for linker in examples and tests --- examples/parallel/fortran/CMakeLists.txt | 1 + examples/serial/fortran/CMakeLists.txt | 1 + tests/fortran/CMakeLists.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/examples/parallel/fortran/CMakeLists.txt b/examples/parallel/fortran/CMakeLists.txt index df227156..f775e664 100644 --- a/examples/parallel/fortran/CMakeLists.txt +++ b/examples/parallel/fortran/CMakeLists.txt @@ -65,6 +65,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) ) set_target_properties(${EXECUTABLE}_fortran_parallel PROPERTIES OUTPUT_NAME ${EXECUTABLE} + LINKER_LANGUAGE Fortran ) target_link_libraries(${EXECUTABLE}_fortran_parallel ${SMARTREDIS_LIBRARIES} diff --git a/examples/serial/fortran/CMakeLists.txt b/examples/serial/fortran/CMakeLists.txt index f1ceed5b..aa8c4231 100644 --- a/examples/serial/fortran/CMakeLists.txt +++ b/examples/serial/fortran/CMakeLists.txt @@ -59,6 +59,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) ) set_target_properties(${EXECUTABLE}_fortran_serial PROPERTIES OUTPUT_NAME ${EXECUTABLE} + LINKER_LANGUAGE Fortran ) target_link_libraries(${EXECUTABLE}_fortran_serial smartredis diff --git a/tests/fortran/CMakeLists.txt b/tests/fortran/CMakeLists.txt index 4d5f7230..4b95a30e 100644 --- a/tests/fortran/CMakeLists.txt +++ b/tests/fortran/CMakeLists.txt @@ -73,6 +73,7 @@ foreach(EXECUTABLE ${EXECUTABLES}) ) set_target_properties(${EXECUTABLE}_fortran_test PROPERTIES OUTPUT_NAME ${EXECUTABLE} + LINKER_LANGUAGE Fortran ) target_link_libraries(${EXECUTABLE}_fortran_test smartredis smartredis-fortran test-utils From 72b4d7163b71b2dbeef97c6cde5bd9c907ad73d0 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Tue, 2 Jul 2024 20:58:14 +0000 Subject: [PATCH 25/25] Cleanup merge --- doc/changelog.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index e0aee20f..50a5070c 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -6,16 +6,13 @@ Released on 14 May 2024 Description -<<<<<<< HEAD - Remove broken oss.redis.com URLs from documentation -======= - Add option to allow SmartRedis Fortran library to retain the path to the main client library - Update examples and tests to use find_package(smartredis) - Generate config files necessary to allow CMake projects to add SmartRedis via find_package - Allow users to specify install location of SmartRedis libraries ->>>>>>> 783e335 (Final changes) - Streamline compilation of SmartRedis dependencies - Pin NumPy version to 1.x - Improve client error logging