hpc_cmake
hpc_cmake
Victor Eijkhout
Fall 2023
4 Example libraries
Parallelism
5 TBB
Data packages
More libraries
or
do everything with CMake:
cmake ## arguments
cmake --build ## stuff
cmake --install ## stuff
dir dir
src src
build build
install install
In-source build: pretty common
Out-of-source build: cleaner because never touches the source tree
Some people skip the install step, and use everything from the build
directory.
Download from
https://eigen.tuxfamily.org/index.php
and install.
What compiler is it finding? If you are at TACC, is it the module you have
loaded?
Compiler settings:
cmake -D CMAKE_CXX_COMPILER=icpx
Alternatively:
export CXX=icpx
cmake .......
CMake leaves behind a log and error file, but these are insufficent:
⇒ use the above verbose mode and capture all output.
or:
cmake \
-D PACKAGE1_INC=/users/my/package1/include \
-D PACKAGE1_LIB=/users/my/package1/lib \
-D PACKAGE2_INC=/users/my/package2/include/package \
-D PACKAGE2_LIB=/users/my/package2/lib64 \
../newpackage
Packages with a .pc file can be found through the pkg-config command:
gcc -o myprogram myprogram.c \
$( pkg-config --cflags package1 ) \
$( pkg-config --libs package1 )
In a makefile:
CFLAGS = -g -O2 $$( pkg-config --cflags package1 )
#include "Eigen/Core"
int main(int argc,char **argv) {
return 0;
}
You have a code that you want to distribute in source form for easy
installation.
You decide to use CMake for portability.
You think that using CMake might make life easier.
⇒ To do: write the CMakeLists.txt file.
(list: C, CXX, CSharp, CUDA, OBJC, OBJCXX, Fortran, HIP, ISPC, Swift,
and a couple of variants of ASM)
Use of macros:
add_executable( ${PROJECT_NAME} )
add_executable( program )
target_sources( program PRIVATE program.cxx )
install( TARGETS program DESTINATION . )
int main() {
// Define a 3x3 matrix
Eigen::Matrix3d matrix;
matrix << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << "Original matrix:\n" << matrix << std::endl;
return 0;
}
4 add_executable( program )
5 target_sources( program PRIVATE program.cxx )
6
7 add_library( auxlib )
8 target_sources( auxlib PRIVATE aux.cxx aux.h )
9
Build both by having two lines, one for shared, one for static.
Related: the -fPIC compile option is set by
CMAKE_POSITION_INDEPENDENT_CODE:
cmake -D CMAKE_POSITION_INDEPENDENT_CODE=ON
4 add_executable( program )
5 target_sources( program PRIVATE program.cxx )
6
5 add_executable( program )
6 target_sources( program PRIVATE program.cxx )
7 add_subdirectory( lib )
8 target_include_directories(
9 program PUBLIC lib )
10 target_link_libraries( program PUBLIC auxlib )
11 install( TARGETS program DESTINATION bin )
(Note that the name of the library comes from the subdirectory)
Use LD_LIBRARY_PATH, or
use rpath.
(Apple note: forced to use second option)
set_target_properties(
${PROGRAM_NAME} PROPERTIES
BUILD_RPATH "${CATCH2_LIBRARY_DIRS};${FMTLIB_LIBRARY_DIRS}"
INSTALL_RPATH "${CATCH2_LIBRARY_DIRS};${FMTLIB_LIBRARY_DIRS}"
)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
Name: @PROJECT_NAME@
Description: @CMAKE_PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -l@libtarget@
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION share/pkgconfig
)
find_package( MPI )
target_include_directories(
${PROJECT_NAME} PUBLIC
${MPI_CXX_INCLUDE_DIRS} )
target_link_libraries(
${PROJECT_NAME} PUBLIC
${MPI_CXX_LIBRARIES} )
find_package( MPI )
target_include_directories(
${PROJECT_NAME} PUBLIC
${MPI_INCLUDE_DIRS} )
target_link_directories(
${PROJECT_NAME} PUBLIC
${MPI_LIBRARY_DIRS} )
target_link_libraries(
${PROJECT_NAME} PUBLIC
${MPI_Fortran_LIBRARIES} )
if( MPI_Fortran_HAVE_F08_MODULE )
else()
message( FATAL_ERROR "No f08 module for this MPI" )
endif()
find_package(OpenMP)
target_link_libraries(
${PROJECT_NAME}
PUBLIC OpenMP::OpenMP_C )
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
else()
message( FATAL_ERROR "Could not find OpenMP" )
endif()
target_link_libraries(
${PROJECT_NAME}
PUBLIC OpenMP::OpenMP_CXX )
enable_language(Fortran)
find_package(OpenMP)
target_link_libraries(
${PROJECT_NAME}
PUBLIC OpenMP::OpenMP_Fortran )
find_package(TBB REQUIRED)
target_link_libraries( ${PROJECT_NAME} PUBLIC TBB::tbb)
find_package(Kokkos REQUIRED)
target_link_libraries(myTarget Kokkos::kokkos)
Maybe:
-DCMAKE_CXX_COMPILER=<Kokkos Install Directory>/bin/
nvcc_wrapper
See https://kokkos.org/kokkos-core-wiki/ProgrammingGuide/
Compiling.html
C:
find_package( PkgConfig REQUIRED )
pkg_check_modules( HDF REQUIRED hdf5 )
message( STATUS "Hdf5 includes: ${HDF_INCLUDE_DIRS}" )
target_include_directories(
${PROJECTNAME} PUBLIC
${HDF_INCLUDE_DIRS}
)
C:
find_package( PkgConfig REQUIRED )
pkg_check_modules( NETCDF REQUIRED netcdf )
target_include_directories(
${PROJECTNAME} PUBLIC
${NETCDF_INCLUDE_DIRS} )
target_link_libraries(
${PROJECTNAME} PUBLIC
${NETCDF_LIBRARIES} )
target_link_directories(
${PROJECTNAME} PUBLIC
${NETCDF_LIBRARY_DIRS} )
target_link_libraries(
${PROJECTNAME} PUBLIC netcdf )
target_include_directories(
${PROJECTNAME} PUBLIC
${NETCDFF_INCLUDE_DIRS}
)
target_link_libraries(
${PROJECTNAME} PUBLIC
${NETCDFF_LIBRARIES} ${NETCDF_LIBRARIES}
)
target_link_directories(
${PROJECTNAME} PUBLIC
${NETCDFF_LIBRARY_DIRS} ${NETCDF_LIBRARY_DIRS}
)
target_link_libraries(
${PROJECTNAME} PUBLIC netcdf )
Package dependent:
Sometimes through pkg-config:
find the .pc file
Sometimes through a Find.... module
see CMake documentation
Header-only:
find_package( PkgConfig REQUIRED )
pkg_check_modules( OPTS REQUIRED cxxopts )
target_include_directories(
${PROGRAM_NAME} PUBLIC
${OPTS_INCLUDE_DIRS}
)
Header-only:
cmake_minimum_required( VERSION 3.12 )
project( eigentest )
add_executable( eigentest )
target_sources( eigentest PRIVATE eigentest.cxx )
target_include_directories(
myprogram PUBLIC
${EIGEN_INCLUDE_DIRS})