|
| 1 | +cmake_minimum_required(VERSION 3.12) |
| 2 | + |
| 3 | +project(cabextract |
| 4 | + VERSION 1.9.1 |
| 5 | + DESCRIPTION "A program to extract Microsoft Cabinet files." |
| 6 | + LANGUAGES C) |
| 7 | + |
| 8 | +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) |
| 9 | + |
| 10 | +include(CMakeOptions.txt) |
| 11 | + |
| 12 | +# Do not disable assertions based on CMAKE_BUILD_TYPE. |
| 13 | +foreach(_build_type Release MinSizeRel RelWithDebInfo) |
| 14 | + foreach(_lang C) |
| 15 | + string(TOUPPER CMAKE_${_lang}_FLAGS_${_build_type} _var) |
| 16 | + string(REGEX REPLACE "(^|)[/-]D *NDEBUG($|)" " " ${_var} "${${_var}}") |
| 17 | + endforeach() |
| 18 | +endforeach() |
| 19 | + |
| 20 | +# Support the latest c++ standard available. |
| 21 | +include(ExtractValidFlags) |
| 22 | +# Determine if _FILE_OFFSET_BITS 64 needs to be set to handle large files. |
| 23 | +include(CheckFileOffsetBits) |
| 24 | +# Define inline macro as needed. |
| 25 | +include(TestInline) |
| 26 | + |
| 27 | +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) |
| 28 | + set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE) |
| 29 | + |
| 30 | + # Include "None" as option to disable any additional (optimization) flags, |
| 31 | + # relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by |
| 32 | + # default). These strings are presented in cmake-gui. |
| 33 | + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS |
| 34 | + None Debug Release MinSizeRel RelWithDebInfo) |
| 35 | +endif() |
| 36 | + |
| 37 | +include(GNUInstallDirs) |
| 38 | + |
| 39 | +# Always use '-fPIC'/'-fPIE' option. |
| 40 | +set(CMAKE_POSITION_INDEPENDENT_CODE ON) |
| 41 | + |
| 42 | +# Checks for header files. |
| 43 | +include(CheckIncludeFile) |
| 44 | +check_include_file(dlfcn.h HAVE_DLFCN_H) |
| 45 | +check_include_file(inttypes.h HAVE_INTTYPES_H) |
| 46 | +check_include_file(stdint.h HAVE_STDINT_H) |
| 47 | +check_include_file(stddef.h HAVE_STDDEF_H) |
| 48 | +check_include_file(limits.h HAVE_LIMITS_H) |
| 49 | +check_include_file(ctype.h HAVE_CTYPE_H) |
| 50 | +check_include_file(wctype.h HAVE_WCTYPE_H) |
| 51 | +check_include_file(errno.h HAVE_ERRNO_H) |
| 52 | +check_include_file(dirent.h HAVE_DIRENT_H) |
| 53 | +check_include_file(sys/types.h HAVE_SYS_TYPES_H) |
| 54 | +check_include_file(sys/stat.h HAVE_SYS_STAT_H) |
| 55 | +check_include_file(fnmatch.h HAVE_FNMATCH_H) |
| 56 | +check_include_file(iconv.h HAVE_ICONV_H) |
| 57 | +check_include_file(locale.h HAVE_LOCALE_H) |
| 58 | +check_include_file(stdarg.h HAVE_STDARG_H) |
| 59 | +check_include_file(stdlib.h HAVE_STDLIB_H) |
| 60 | +check_include_file(string.h HAVE_STRING_H) |
| 61 | +check_include_file(strings.h HAVE_STRINGS_H) |
| 62 | +check_include_file(sys/time.h HAVE_SYS_TIME_H) |
| 63 | +check_include_file(float.h HAVE_FLOAT_H) |
| 64 | +check_include_file(unistd.h HAVE_UNISTD_H) |
| 65 | + |
| 66 | +include(CheckIncludeFiles) |
| 67 | +check_include_files("dlfcn.h;stdint.h;stddef.h;inttypes.h;stdlib.h;strings.h;string.h;float.h" StandardHeadersExist) |
| 68 | +if(StandardHeadersExist) |
| 69 | + set(STDC_HEADERS 1 CACHE INTERNAL "System has ANSI C header files") |
| 70 | +else() |
| 71 | + message(STATUS "ANSI C header files - not found") |
| 72 | + set(STDC_HEADERS 0 CACHE INTERNAL "System has ANSI C header files") |
| 73 | +endif() |
| 74 | + |
| 75 | + |
| 76 | +# Checks for library functions. |
| 77 | +include(CheckFunctionExists) |
| 78 | +check_function_exists(fseeko HAVE_FSEEKO) |
| 79 | +check_function_exists(mkdir HAVE_MKDIR) |
| 80 | +check_function_exists(_mkdir HAVE__MKDIR) |
| 81 | +check_function_exists(towlower HAVE_TOWLOWER) |
| 82 | + |
| 83 | +# Check size of types. |
| 84 | +include(CheckTypeSize) |
| 85 | +check_type_size("off_t" SIZEOF_OFF_T) |
| 86 | +if(NOT SIZEOF_OFF_T) |
| 87 | + # Set it to "long int" to match the behavior of AC_TYPE_OFF_T (autotools). |
| 88 | + set(OFF_T_DEF "typedef int off_t;") |
| 89 | +endif() |
| 90 | + |
| 91 | +check_type_size("size_t" SIZEOF_SIZE_T) |
| 92 | +if(NOT SIZEOF_SIZE_T) |
| 93 | + # Set it to "unsigned int" to match the behavior of AC_TYPE_SIZE_T (autotools). |
| 94 | + set(SIZE_T_DEF "typedef int size_t;") |
| 95 | +endif() |
| 96 | + |
| 97 | +check_type_size("ssize_t" SIZEOF_SSIZE_T) |
| 98 | +if(NOT SIZEOF_SSIZE_T) |
| 99 | + # Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools). |
| 100 | + set(SSIZE_T_DEF "typedef int ssize_t;") |
| 101 | +endif() |
| 102 | + |
| 103 | +check_type_size("mode_t" SIZEOF_MODE_T) |
| 104 | +if(NOT SIZEOF_MODE_T) |
| 105 | + # Set it to "int" to match the behavior of AC_TYPE_MODE_T (autotools). |
| 106 | + set(MODE_T_DEF "typedef int mode_t;") |
| 107 | +endif() |
| 108 | + |
| 109 | +# Compile tests |
| 110 | +try_compile(MKDIR_TAKES_ONE_ARG ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/cmake/compiletest_mkdir.c) |
| 111 | + |
| 112 | +# Check if big-endian |
| 113 | +include(TestBigEndian) |
| 114 | +TEST_BIG_ENDIAN(WORDS_BIGENDIAN) |
| 115 | + |
| 116 | +set(WARNCFLAGS) |
| 117 | +if(CMAKE_C_COMPILER_ID MATCHES "MSVC") |
| 118 | + if(ENABLE_WERROR) |
| 119 | + set(WARNCFLAGS /WX) |
| 120 | + endif() |
| 121 | +else() |
| 122 | + if(ENABLE_WERROR) |
| 123 | + extract_valid_c_flags(WARNCFLAGS -Werror) |
| 124 | + endif() |
| 125 | + |
| 126 | + # For C compiler |
| 127 | + extract_valid_c_flags(WARNCFLAGS |
| 128 | + -Wall |
| 129 | + -Wextra |
| 130 | + -Wmissing-prototypes |
| 131 | + -Wstrict-prototypes |
| 132 | + -Wmissing-declarations |
| 133 | + -Wpointer-arith |
| 134 | + -Wdeclaration-after-statement |
| 135 | + -Wformat-security |
| 136 | + -Wwrite-strings |
| 137 | + -Wshadow |
| 138 | + -Winline |
| 139 | + -Wnested-externs |
| 140 | + -Wfloat-equal |
| 141 | + -Wundef |
| 142 | + -Wendif-labels |
| 143 | + -Wempty-body |
| 144 | + -Wcast-align |
| 145 | + -Wclobbered |
| 146 | + -Wvla |
| 147 | + -Wpragmas |
| 148 | + -Wunreachable-code |
| 149 | + -Waddress |
| 150 | + -Wattributes |
| 151 | + -Wdiv-by-zero |
| 152 | + -Wshorten-64-to-32 |
| 153 | + -Wconversion |
| 154 | + -Wextended-offsetof |
| 155 | + -Wformat-nonliteral |
| 156 | + -Wlanguage-extension-token |
| 157 | + -Wmissing-field-initializers |
| 158 | + -Wmissing-noreturn |
| 159 | + -Wmissing-variable-declarations |
| 160 | + # -Wpadded # Not used because we cannot change public structs |
| 161 | + -Wsign-conversion |
| 162 | + # -Wswitch-enum # Not used because this basically disallows default case |
| 163 | + -Wunreachable-code-break |
| 164 | + -Wunused-macros |
| 165 | + -Wunused-parameter |
| 166 | + -Wredundant-decls |
| 167 | + -Wheader-guard |
| 168 | + #-Wno-format-nonliteral # This is required because we pass format string as "const char*. |
| 169 | + -Wno-unused-parameter |
| 170 | + -Wno-unused-result |
| 171 | + ) |
| 172 | +endif() |
| 173 | + |
| 174 | +if(ENABLE_DEBUG) |
| 175 | + set(DEBUGBUILD 1) |
| 176 | +endif() |
| 177 | + |
| 178 | +# autotools-compatible names |
| 179 | +# Sphinx expects relative paths in the .rst files. Use the fact that the files |
| 180 | +# below are all one directory level deep. |
| 181 | +file(RELATIVE_PATH top_srcdir ${CMAKE_CURRENT_BINARY_DIR}/dir ${CMAKE_CURRENT_SOURCE_DIR}) |
| 182 | +file(RELATIVE_PATH top_builddir ${CMAKE_CURRENT_BINARY_DIR}/dir ${CMAKE_CURRENT_BINARY_DIR}) |
| 183 | +set(abs_top_srcdir ${CMAKE_CURRENT_SOURCE_DIR}) |
| 184 | +set(abs_top_builddir ${CMAKE_CURRENT_BINARY_DIR}) |
| 185 | + |
| 186 | +set(prefix ${CMAKE_INSTALL_PREFIX}) |
| 187 | +set(exec_prefix ${CMAKE_INSTALL_PREFIX}) |
| 188 | +set(bindir ${CMAKE_INSTALL_FULL_BINDIR}) |
| 189 | +set(sbindir ${CMAKE_INSTALL_FULL_SBINDIR}) |
| 190 | +set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}) |
| 191 | +set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}) |
| 192 | +set(VERSION ${PROJECT_VERSION}) |
| 193 | + |
| 194 | +# Generate config.h |
| 195 | +add_definitions(-DHAVE_CONFIG_H) |
| 196 | +configure_file(config.h.in.cmake config.h) |
| 197 | +include_directories(${PROJECT_BINARY_DIR}) |
| 198 | + |
| 199 | +# |
| 200 | +# The build targets. |
| 201 | +# |
| 202 | +if(NOT ENABLE_EXTERNAL_MSPACK) |
| 203 | + include_directories(../libmspack/mspack) |
| 204 | + add_subdirectory(../libmspack ${PROJECT_BINARY_DIR}/libmspack) |
| 205 | +else() |
| 206 | + find_package(MSPack) |
| 207 | +endif() |
| 208 | + |
| 209 | +add_executable(cabextract) |
| 210 | +target_sources(cabextract |
| 211 | + PRIVATE |
| 212 | + src/cabextract.c |
| 213 | + getopt.c getopt.h |
| 214 | + getopt1.c |
| 215 | + md5.h md5.c) |
| 216 | +if(NOT WIN32) |
| 217 | + target_include_directories(cabextract PRIVATE ${PROJECT_SOURCE_DIR}) |
| 218 | +else() |
| 219 | + target_include_directories(cabextract PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/win32) |
| 220 | + target_sources(cabextract PRIVATE win32/dirent.h) |
| 221 | + target_link_libraries(cabextract Shlwapi.lib) |
| 222 | +endif() |
| 223 | +target_include_directories(cabextract PRIVATE ${PROJECT_SOURCE_DIR}) |
| 224 | +target_link_libraries(cabextract MSPack::mspack) |
| 225 | +install(TARGETS cabextract DESTINATION ${CMAKE_INSTALL_BINDIR}) |
| 226 | + |
| 227 | +if(NOT WIN32) |
| 228 | + add_executable(cabinfo) |
| 229 | + target_sources(cabinfo |
| 230 | + PRIVATE |
| 231 | + src/cabinfo.c) |
| 232 | + target_include_directories(cabinfo PRIVATE ${PROJECT_SOURCE_DIR}) |
| 233 | + target_link_libraries(cabinfo MSPack::mspack) |
| 234 | + |
| 235 | + enable_testing() |
| 236 | + add_subdirectory(test) |
| 237 | +endif() |
| 238 | + |
| 239 | +# |
| 240 | +# The Summary Info. |
| 241 | +# |
| 242 | +string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type) |
| 243 | +message(STATUS "Summary of build options: |
| 244 | +
|
| 245 | + Package version: ${VERSION} |
| 246 | + Install prefix: ${CMAKE_INSTALL_PREFIX} |
| 247 | + Target system: ${CMAKE_SYSTEM_NAME} |
| 248 | + Compiler: |
| 249 | + Build type: ${CMAKE_BUILD_TYPE} |
| 250 | + C compiler: ${CMAKE_C_COMPILER} |
| 251 | + CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} |
| 252 | + WARNCFLAGS: ${WARNCFLAGS} |
| 253 | + Features: |
| 254 | + External mspack: ${ENABLE_EXTERNAL_MSPACK} |
| 255 | +") |
0 commit comments