Skip to content

Commit

Permalink
Merge pull request #1 from palmerb4/cmake_update
Browse files Browse the repository at this point in the history
Revised our CMake installation and build routines.
  • Loading branch information
Shihab-Shahriar authored Mar 11, 2024
2 parents 3bd0960 + 95e6901 commit 1567f6b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 82 deletions.
128 changes: 75 additions & 53 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,95 +1,117 @@
# TODO: Lower the min version required
cmake_minimum_required(VERSION 3.18)

# Project's name
project(OpenRAND VERSION 1.0)

# Set the C++ standard
# Set the C++ standard and ensure it's strictly required
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#- Wdouble-promotion : implicit float->double promotion is a really bad idea for GPU
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wall -Wextra -Wdouble-promotion -Wconversion -O3 -fopenmp")

include_directories(${PROJECT_SOURCE_DIR}/include)
# Define the main library as an interface
add_library(${PROJECT_NAME} INTERFACE)

include(FetchContent)
# Create an alias target for users to include OpenRAND with a namespace
# This isn't explicitly necessary as OpenRAND is header-only but it takes including OpenRAND
# via find_package + target_link_libraries straightforward.
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

# Specify the C++ flags using target_compile_options and generator expressions for better control and compatibility
target_compile_options(${PROJECT_NAME} INTERFACE
$<$<CXX_COMPILER_ID:GNU>:
-Wall -Wextra -Wdouble-promotion -Wconversion -O3>
$<$<CXX_COMPILER_ID:Clang>:
-Wall -Wextra -Wconversion -O3>
$<$<CXX_COMPILER_ID:MSVC>:
/W4 /O2>
)

# Build TestU01 statistical test suite
set(TESTU01_PATH "" CACHE PATH "Path to TestU01 library")
# Include directories for the interface target
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

# Only build tests, examples and benchmarks if this isn't compiled
# as a dependecy of another project.
# Thanks to: https://www.foonathan.net/2022/06/cmake-fetchcontent/
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
enable_testing()
add_subdirectory(tests)

add_subdirectory(examples)
add_subdirectory(benchmarks)
# Options to control the build process
option(OpenRAND_ENABLE_TESTS "Enable building of tests" OFF)
option(OpenRAND_ENABLE_EXAMPLES "Enable building of examples" OFF)
option(OpenRAND_ENABLE_BENCHMARKS "Enable building of benchmarks" OFF)

message(STATUS "OpenRAND_ENABLE_TESTS: ${OpenRAND_ENABLE_TESTS}")
message(STATUS "OpenRAND_ENABLE_EXAMPLES: ${OpenRAND_ENABLE_EXAMPLES}")
message(STATUS "OpenRAND_ENABLE_BENCHMARKS: ${OpenRAND_ENABLE_BENCHMARKS}")

if(OpenRAND_ENABLE_TESTS)
# Fetch GoogleTest for managing tests
include(FetchContent)

FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) # Prevent GTest from being installed
FetchContent_MakeAvailable(googletest)

enable_testing()
add_subdirectory(tests)
endif()

if(OpenRAND_ENABLE_EXAMPLES)
add_subdirectory(examples)
endif()

# TODO: it's still being built as DEBUG
if(OpenRAND_ENABLE_BENCHMARKS)
# Fetch GoogleBenchmarks for managing benchmarks
include(FetchContent)
FetchContent_Declare(
google_benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG main
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
google_benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG main
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release # TODO: it's still being built as DEBUG
)
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) # Prevent GoogleBenchmarks from being installed
FetchContent_MakeAvailable(google_benchmark)

add_subdirectory(benchmarks)
endif()

# Installation rules for the library
include(GNUInstallDirs)

add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME}
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

# Rules to install the library in system
# It follows the guide in: https://dominikberner.ch/cmake-interface-lib/

# Export the targets
# Installation rules for the library
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
INCLUDES DESTINATION include)

EXPORT ${PROJECT_NAME}Targets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Exporting and installing the package configuration
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${PROJECT_NAME}ConfigVersion.cmake
"${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)

# Create and install the export file
install(EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)

# Copy entire openrand directory
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/openrand DESTINATION include)
# Install the include directory
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/openrand
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
14 changes: 6 additions & 8 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
add_executable(raw_speed_cpu raw_speed_cpu.cpp)
target_include_directories(raw_speed_cpu PRIVATE ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(raw_speed_cpu benchmark::benchmark)

target_link_libraries(raw_speed_cpu PRIVATE benchmark::benchmark ${PROJECT_NAME})

include(CheckLanguage)
check_language(CUDA)
if (CMAKE_CUDA_COMPILER)
message(STATUS "CUDA FOUND: building CUDA benchmarks")
enable_language(CUDA)
add_executable(raw_speed_cuda raw_speed_cuda.cu)
target_include_directories(raw_speed_cuda PRIVATE ${CMAKE_SOURCE_DIR}/include)
message(STATUS "CUDA FOUND: Building CUDA benchmarks")
enable_language(CUDA)
add_executable(raw_speed_cuda raw_speed_cuda.cu)
target_link_libraries(raw_speed_cuda PRIVATE ${PROJECT_NAME})
else()
message(STATUS "skipping: CUDA benchmarks, CUDA not found")
message(STATUS "CUDA not found: Skipping CUDA benchmarks")
endif()
1 change: 0 additions & 1 deletion benchmarks/raw_speed_cuda.cu
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <cub/cub.cuh>
#include <cuda.h>


#include <openrand/philox.h>
#include <openrand/threefry.h>
#include <openrand/squares.h>
Expand Down
33 changes: 23 additions & 10 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
# Add the executable
add_executable(basic_usage basic_usage.cpp)
add_executable(pi_openmp pi_openmp.cpp)
add_executable(serial_parallel_equivalence state_forwarding.cpp)
# OpenMP-dependent examples
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
message(STATUS "OpenMP FOUND: Building OpenMP examples")

add_executable(serial_parallel_equivalence state_forwarding.cpp)
target_link_libraries(serial_parallel_equivalence PRIVATE OpenMP::OpenMP_CXX ${PROJECT_NAME})

add_executable(basic_usage basic_usage.cpp)
target_link_libraries(basic_usage PRIVATE OpenMP::OpenMP_CXX ${PROJECT_NAME})

add_executable(pi_openmp pi_openmp.cpp)
target_link_libraries(pi_openmp PRIVATE OpenMP::OpenMP_CXX ${PROJECT_NAME})
else()
message(STATUS "OpenMP not found: Skipping OpenMP examples")
endif()

# MPI examples
include(CheckLanguage)
check_language(CUDA)
if (CMAKE_CUDA_COMPILER)
message(STATUS "CUDA FOUND: building CUDA examples")
enable_language(CUDA)
add_executable(pi_cuda pi_cuda.cu)
target_include_directories(pi_cuda PRIVATE ${CMAKE_SOURCE_DIR}/include)
set_property(TARGET pi_cuda PROPERTY CUDA_STANDARD 17)
message(STATUS "CUDA FOUND: Building CUDA examples")
enable_language(CUDA)

add_executable(pi_cuda pi_cuda.cu)
target_link_libraries(pi_cuda PRIVATE ${PROJECT_NAME})
set_property(TARGET pi_cuda PROPERTY CUDA_STANDARD 17)
else()
message(STATUS "skipping: CUDA examples, CUDA not found")
message(STATUS "CUDA not found: Skipping CUDA examples")
endif()

20 changes: 10 additions & 10 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
find_package(Python COMPONENTS Interpreter REQUIRED)


enable_testing()

add_executable(
uniform
test_uniform.cpp
)
target_link_libraries(
uniform
GTest::gtest_main
uniform PRIVATE GTest::gtest_main ${PROJECT_NAME}
)

add_executable(
normal
test_normal.cpp
)
target_link_libraries(
normal
GTest::gtest_main
normal PRIVATE GTest::gtest_main ${PROJECT_NAME}
)

add_executable(
base
test_base.cpp
)
target_link_libraries(
base
GTest::gtest_main
base PRIVATE GTest::gtest_main ${PROJECT_NAME}
)

include(GoogleTest)
Expand All @@ -39,16 +35,20 @@ gtest_discover_tests(base)
# Statistical tests, not run through gtest framework
add_executable(pract_rand pract_rand.cpp)
add_executable(pract_rand_multi pract_rand_multistream.cpp)
target_link_libraries(pract_rand ${PROJECT_NAME})
target_link_libraries(pract_rand_multi ${PROJECT_NAME})

if(NOT TESTU01_PATH STREQUAL "")
OPTION(TESTU01_PATH "Path to the TestU01 library" "")
MESSAGE(STATUS "TESTU01_PATH: ${TESTU01_PATH}")
if(TESTU01_PATH)
message(STATUS "Building TESTU01 statistical test suite")
link_directories(${TESTU01_PATH}/lib)
add_executable(testu01_serial testu01.cpp)
target_link_libraries(testu01_serial testu01 probdist mylib)
target_link_libraries(testu01_serial testu01 probdist mylib ${PROJECT_NAME})
target_include_directories(testu01_serial PUBLIC ${TESTU01_PATH}/include)

add_executable(testu01_multi testu01-multistream.cpp)
target_link_libraries(testu01_multi testu01 probdist mylib)
target_link_libraries(testu01_multi testu01 probdist mylib ${PROJECT_NAME})
target_include_directories(testu01_multi PUBLIC ${TESTU01_PATH}/include)
else()
message(STATUS "TESTU01_PATH not set, not building statistical test suite")
Expand Down

0 comments on commit 1567f6b

Please sign in to comment.