diff --git a/cmake/libsocketcan.cmake b/cmake/libsocketcan.cmake index 81339e5a..d51828f2 100644 --- a/cmake/libsocketcan.cmake +++ b/cmake/libsocketcan.cmake @@ -1,33 +1,86 @@ -FetchContent_Declare( - libsocketcan - GIT_REPOSITORY https://github.com/linux-can/libsocketcan.git - GIT_TAG v0.0.12 +include(ExternalProject) + +set(LIBSOCKETCAN_DEFAULT_URL + "https://github.com/linux-can/libsocketcan/archive/refs/tags/v0.0.12.zip" +) + +set(LIBSOCKETCAN_DEFAULT_HASH + "SHA256=e634d623990f63b4d67beb5a40daf5db73fb37d1a3b3acf68265b60f3f389fbf" +) + +set(LIBSOCKETCAN_URL "${LIBSOCKETCAN_DEFAULT_URL}" + CACHE STRING "URL used to download libsocketcan" ) -FetchContent_MakeAvailable(libsocketcan) +set(LIBSOCKETCAN_HASH "" + CACHE STRING "Checksum for libsocketcan download. If empty, default URL uses built-in checksum and custom URLs skip verification." +) + +set(_libsocketcan_url_hash) + +if(LIBSOCKETCAN_HASH) + set(_libsocketcan_url_hash URL_HASH "${LIBSOCKETCAN_HASH}") +elseif(LIBSOCKETCAN_URL STREQUAL LIBSOCKETCAN_DEFAULT_URL) + set(_libsocketcan_url_hash URL_HASH "${LIBSOCKETCAN_DEFAULT_HASH}") +endif() + +find_program(SH_EXE NAMES sh bash REQUIRED) +find_program(MAKE_EXE NAMES gmake make REQUIRED) + +set(LIBSOCKETCAN_PREFIX_DIR "${CMAKE_BINARY_DIR}/_deps/libsocketcan") +set(LIBSOCKETCAN_SOURCE_DIR "${LIBSOCKETCAN_PREFIX_DIR}/src") +set(LIBSOCKETCAN_BUILD_DIR "${LIBSOCKETCAN_PREFIX_DIR}/build") +set(LIBSOCKETCAN_INSTALL_DIR "${LIBSOCKETCAN_PREFIX_DIR}/install") -set(LIBSOCKETCAN_INCLUDE_DIR ${libsocketcan_SOURCE_DIR}/include) +set(LIBSOCKETCAN_INCLUDE_DIR "${LIBSOCKETCAN_INSTALL_DIR}/include") +set(LIBSOCKETCAN_LIBRARY "${LIBSOCKETCAN_INSTALL_DIR}/lib/libsocketcan.a") -set(LIBSOCKETCAN_LIB ${libsocketcan_SOURCE_DIR}/src/.libs/libsocketcan.a) +# Avoid CMake errors for imported targets whose include directory does not exist +# yet at configure time. +file(MAKE_DIRECTORY "${LIBSOCKETCAN_INCLUDE_DIR}") +file(MAKE_DIRECTORY "${LIBSOCKETCAN_INSTALL_DIR}/lib") -add_custom_command( - OUTPUT ${LIBSOCKETCAN_LIB} - WORKING_DIRECTORY ${libsocketcan_SOURCE_DIR} - COMMAND bash autogen.sh - COMMAND bash configure --enable-static --disable-shared CFLAGS=-fPIC CXXFLAGS=-fPIC - COMMAND make - DEPENDS ${libsocketcan_SOURCE_DIR} +ExternalProject_Add(libsocketcan_external + URL "${LIBSOCKETCAN_URL}" + ${_libsocketcan_url_hash} + + DOWNLOAD_EXTRACT_TIMESTAMP FALSE + + SOURCE_DIR "${LIBSOCKETCAN_SOURCE_DIR}" + BINARY_DIR "${LIBSOCKETCAN_BUILD_DIR}" + INSTALL_DIR "${LIBSOCKETCAN_INSTALL_DIR}" + + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E chdir + ${SH_EXE} ./autogen.sh + COMMAND + ${CMAKE_COMMAND} -E env + "CFLAGS=-fPIC" + "CXXFLAGS=-fPIC" + /configure + --prefix= + --enable-static + --disable-shared + + BUILD_COMMAND + ${MAKE_EXE} + + INSTALL_COMMAND + ${MAKE_EXE} install + + BUILD_BYPRODUCTS + "${LIBSOCKETCAN_LIBRARY}" + + USES_TERMINAL_CONFIGURE TRUE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_INSTALL TRUE ) add_library(libsocketcan STATIC IMPORTED GLOBAL) set_target_properties(libsocketcan PROPERTIES - IMPORTED_LOCATION ${LIBSOCKETCAN_LIB} - INTERFACE_INCLUDE_DIRECTORIES ${LIBSOCKETCAN_INCLUDE_DIR} -) - -add_custom_target(libsocketcan_build ALL - DEPENDS ${LIBSOCKETCAN_LIB} + IMPORTED_LOCATION "${LIBSOCKETCAN_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBSOCKETCAN_INCLUDE_DIR}" ) -add_dependencies(libsocketcan libsocketcan_build) +add_dependencies(libsocketcan libsocketcan_external) diff --git a/cmake/version.cmake b/cmake/version.cmake index 8e2e32dc..a3c6a581 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -3,6 +3,7 @@ execute_process( WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET ) execute_process( @@ -10,7 +11,17 @@ execute_process( WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT_DATE OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET ) + +if(NOT GIT_COMMIT_HASH) + set(GIT_COMMIT_HASH "unknown") +endif() + +if(NOT GIT_COMMIT_DATE) + set(GIT_COMMIT_DATE "unknown") +endif() + configure_file ( "${PROJECT_SOURCE_DIR}/src/include/CanVersion.h.in" "${PROJECT_BINARY_DIR}/src/include/CanVersion.h" diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index d6453636..965d31fd 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -3,10 +3,22 @@ ## Dependencies -- In Linux, you must install the `libsocketcan-devel` package. +- On Linux, `libsocketcan` is downloaded and built automatically by CMake. +- If you need to use a mirrored or internal source, configure it with `LIBSOCKETCAN_URL`. +- If `LIBSOCKETCAN_HASH` is set (for example `SHA256=...`), CMake verifies the download checksum with that value. +- If `LIBSOCKETCAN_HASH` is not set and `LIBSOCKETCAN_URL` is left at its default value, CMake verifies the download with the built-in default hash. +- If `LIBSOCKETCAN_HASH` is not set and `LIBSOCKETCAN_URL` is customized, checksum verification is not performed. - Other dependencies are resolved automatically after setting the variable `ICS_REPO_DEPS_TOKEN=[value]` to your environment (`.env` file). The value is in the group `jcop-opc-ua` configuration of Gitlab CI/CD (gitlab.cern.ch). +Example: + +```bash +cmake -S . -B build \ + -DLIBSOCKETCAN_URL=https:///libsocketcan-v0.0.12.zip \ + -DLIBSOCKETCAN_HASH=SHA256= +``` + ## Development environment - Alma 9 diff --git a/docs/README.md b/docs/README.md index c94bb150..2c9a91ec 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,7 +30,10 @@ The project requires LogIt (part of the Quasar Framework) and it is downloaded a Inside CERN, the CMake will also download the Anagate API. If not, please modify the address to download the API directly from anagate.de -For Linux, the user must install `libsocketcan` and the matching devel package. +For Linux, `libsocketcan` is fetched and built automatically during CMake configuration. You can override +the download source with `LIBSOCKETCAN_URL`. If `LIBSOCKETCAN_HASH` is provided, CMake verifies the +download checksum with that value. If no hash is provided, the default URL is still verified with its +built-in hash, while custom URLs are downloaded without checksum verification. Optionally, the user must install pybind11 to generate the Python bindings.