# ════════════════════════════════════════════════════════════════════════════ # GNU-free CMake build for dosfstools (FenrirOS) # # Replaces dosfstools' autotools (configure.ac/Makefile.am) build with CMake so # the FAT tools (mkfs.fat, fsck.fat, fatlabel) build with the musl/LLVM # toolchain driven by ninja — no autoreconf/automake/GNU-make required. # # dosfstools does NOT use a config.h: its configure.ac has no AC_CONFIG_HEADERS, # so the autoconf build passes the feature macros via -D on the compile line # (@DEFS@). We reproduce that here by probing the platform with CMake's # check_* modules and adding the resulting -D HAVE_* defines globally. version.h # (the only generated header the sources #include) is produced via configure_file. # ════════════════════════════════════════════════════════════════════════════ cmake_minimum_required(VERSION 3.13) project(dosfstools C) include(CheckIncludeFile) include(CheckSymbolExists) # dosfstools is GPLv3; version string comes from configure.ac's AC_INIT. set(PACKAGE_VERSION "4.2" CACHE STRING "dosfstools version") string(TIMESTAMP RELEASE_DATE "%Y-%m-%d") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() # vasprintf/getmntent live behind _GNU_SOURCE in musl; turn it on everywhere # (matches the autotools build's AC_USE_SYSTEM_EXTENSIONS). add_compile_definitions(_GNU_SOURCE) # ICONV_CONST is normally emitted by autoconf's AC_FUNC_ICONV: it is `const` # when iconv()'s 2nd argument is `const char **`, else empty. musl declares it # as plain `char **`, so define it empty (charconv.c references it unguarded). add_compile_definitions(ICONV_CONST=) add_compile_options(-O2 -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers) # ── Platform feature probes → -D HAVE_* (mirrors configure.ac's checks) ────── check_include_file("endian.h" HAVE_ENDIAN_H) check_include_file("sys/endian.h" HAVE_SYS_ENDIAN_H) check_include_file("libkern/OSByteOrder.h" HAVE_LIBKERN_OSBYTEORDER_H) check_include_file("sys/sysmacros.h" HAVE_SYS_SYSMACROS_H) check_include_file("sys/queue.h" HAVE_SYS_QUEUE_H) check_include_file("sys/disk.h" HAVE_SYS_DISK_H) check_include_file("sys/disklabel.h" HAVE_SYS_DISKLABEL_H) check_include_file("linux/loop.h" HAVE_LINUX_LOOP_H) check_include_file("linux/fd.h" HAVE_LINUX_FD_H) check_include_file("linux/hdreg.h" HAVE_LINUX_HDREG_H) check_include_file("iconv.h" HAVE_ICONV) check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF) check_symbol_exists(getmntent "mntent.h" HAVE_DECL_GETMNTENT) check_symbol_exists(getmntinfo "sys/mount.h" HAVE_DECL_GETMNTINFO) # Emit each positive probe as the -DHAVE_X=1 the sources expect; the two # HAVE_DECL_* macros are referenced with `#if`, so define them to 0 when absent. foreach(_m HAVE_ENDIAN_H HAVE_SYS_ENDIAN_H HAVE_LIBKERN_OSBYTEORDER_H HAVE_SYS_SYSMACROS_H HAVE_SYS_QUEUE_H HAVE_SYS_DISK_H HAVE_SYS_DISKLABEL_H HAVE_LINUX_LOOP_H HAVE_LINUX_FD_H HAVE_LINUX_HDREG_H HAVE_ICONV HAVE_VASPRINTF) if(${_m}) add_compile_definitions(${_m}=1) endif() endforeach() if(HAVE_DECL_GETMNTENT) add_compile_definitions(HAVE_DECL_GETMNTENT=1) else() add_compile_definitions(HAVE_DECL_GETMNTENT=0) endif() if(HAVE_DECL_GETMNTINFO) add_compile_definitions(HAVE_DECL_GETMNTINFO=1) else() add_compile_definitions(HAVE_DECL_GETMNTINFO=0) endif() # version.h --- the one header the sources generate (VERSION / VERSION_DATE). configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/src/version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/version.h" @ONLY) include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/src" "${CMAKE_CURRENT_BINARY_DIR}") # generated version.h # ── Source groups (mirror src/Makefile.am) ────────────────────────────────── set(_charconv src/charconv.c) set(_fscklabel src/boot.c src/common.c src/fat.c src/io.c ${_charconv}) set(_devinfo src/device_info.c src/blkdev/blkdev.c src/blkdev/linux_version.c) # fsck.fat add_executable(fsck.fat src/check.c src/file.c src/fsck.fat.c src/lfn.c ${_fscklabel}) # fatlabel add_executable(fatlabel src/fatlabel.c ${_fscklabel}) # mkfs.fat (needs the blkdev/ headers and device_info) add_executable(mkfs.fat src/mkfs.fat.c src/common.c ${_charconv} ${_devinfo}) target_include_directories(mkfs.fat PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/blkdev") # musl provides iconv in libc, so no separate -liconv is required. install(TARGETS fsck.fat fatlabel mkfs.fat RUNTIME DESTINATION sbin) # Traditional compatibility names (configure.ac COMPAT_SYMLINKS / install-hook). install(CODE " set(_sb \"\${CMAKE_INSTALL_PREFIX}/sbin\") file(CREATE_LINK fatlabel \"\${_sb}/dosfslabel\" SYMBOLIC) file(CREATE_LINK fsck.fat \"\${_sb}/dosfsck\" SYMBOLIC) file(CREATE_LINK fsck.fat \"\${_sb}/fsck.msdos\" SYMBOLIC) file(CREATE_LINK fsck.fat \"\${_sb}/fsck.vfat\" SYMBOLIC) file(CREATE_LINK mkfs.fat \"\${_sb}/mkdosfs\" SYMBOLIC) file(CREATE_LINK mkfs.fat \"\${_sb}/mkfs.msdos\" SYMBOLIC) file(CREATE_LINK mkfs.fat \"\${_sb}/mkfs.vfat\" SYMBOLIC) ")