First of all, please don’t lecture me about using crypt() – I know what it does and what it does not. I have a little C program that is supposed to use the very crypt() that the OS is using to check user passwords (assuming it does, I know OpenBSD does not).
However, crypt() is a little different in every libc: some require unistd.h, some require crypt.h, some require no extra libraries, some require -lcrypt. And there’s libxcrypt as well, which is starting to replace glibc’s long deprecated crypt().
Long story short: I’m new to CMake, and while checking for something with FindSomething.cmake or pkg-config is easy, checking for which demons to invoke for libc crypt() is not, and I feel like I’m doing it wrong. It works, but looks way too complicated.
Also, I’d like to try using libxcrypt if crypt() wasn’t found with other methods. How can I do that without repeating half the checks?
cmake_minimum_required(VERSION 3.10)
project(pwhash)
set(USE_LIBXCRYPT OFF CACHE BOOL "Use libxcrypt for crypt()")
find_package(PkgConfig REQUIRED)
add_executable(pwhash pwhash.c)
if(USE_LIBXCRYPT)
pkg_check_modules(LIBXCRYPT IMPORTED_TARGET REQUIRED libxcrypt)
target_link_libraries(pwhash PUBLIC PkgConfig::LIBXCRYPT)
target_compile_definitions(pwhash PUBLIC HAVE_CRYPT_H)
else()
include(CheckIncludeFile)
check_include_file(crypt.h HAVE_CRYPT_H)
if(HAVE_CRYPT_H)
list(APPEND CMAKE_REQUIRED_INCLUDES "crypt.h")
target_compile_definitions(pwhash PUBLIC HAVE_CRYPT_H)
endif()
include(CheckSymbolExists)
unset(HAVE_CRYPT CACHE)
check_symbol_exists(crypt "unistd.h" HAVE_CRYPT)
if(NOT HAVE_CRYPT)
unset(HAVE_CRYPT CACHE)
list(APPEND CMAKE_REQUIRED_LIBRARIES "crypt")
check_symbol_exists(crypt "unistd.h" HAVE_CRYPT)
if(HAVE_CRYPT)
target_link_libraries(pwhash PUBLIC crypt)
else()
error("No crypt() found")
endif()
endif()
endif()