CMakeLists.txt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
  2. project(jpegoptim C)
  3. # LIBJPEG_INCLUDE_DIR and LIBJPEG_LIBRARY must both be specified if a custom libjpeg implementation is desired.
  4. option(WITH_ARITH "Enable arithmetic coding (if supported by the libjpeg implementation)" 1)
  5. option(USE_MOZJPEG "Download, build, and link with MozJPEG rather than the system libjpeg. Build with NASM installed for SIMD support." 1)
  6. option(BUILD_FUZZERS "Build harnesses with instrumentation" 0)
  7. set(LIBJPEG_INCLUDE_DIR "" CACHE PATH "Custom libjpeg header directory")
  8. set(LIBJPEG_LIBRARY "" CACHE FILEPATH "Custom libjpeg library binary")
  9. if(MSVC)
  10. option(BUILD_NO_SUBFOLDERS "Flatten the compiled program's output path")
  11. endif()
  12. # If LIBJPEG_INCLUDE_DIR and LIBJPEG_LIBRARY are set, USE_MOZJPEG is disabled.
  13. if(LIBJPEG_INCLUDE_DIR AND LIBJPEG_LIBRARY)
  14. set(USE_MOZJPEG 0)
  15. endif()
  16. # Set target architecture if empty. CMake's Visual Studio generator provides it, but others may not.
  17. if(MSVC)
  18. if(NOT CMAKE_VS_PLATFORM_NAME)
  19. set(CMAKE_VS_PLATFORM_NAME "x64")
  20. endif()
  21. message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
  22. else()
  23. add_compile_definitions(HOST_TYPE="${CMAKE_HOST_SYSTEM_NAME}")
  24. endif()
  25. # Global configuration types
  26. set(CMAKE_CONFIGURATION_TYPES
  27. "Debug"
  28. "Release"
  29. CACHE STRING "" FORCE
  30. )
  31. # Global compiler options
  32. if(MSVC)
  33. # remove default compiler flags provided with CMake for MSVC
  34. set(CMAKE_C_FLAGS "")
  35. set(CMAKE_C_FLAGS_DEBUG "")
  36. set(CMAKE_C_FLAGS_RELEASE "")
  37. endif()
  38. # Global linker options
  39. if(MSVC)
  40. # remove default linker flags provided with CMake for MSVC
  41. set(CMAKE_EXE_LINKER_FLAGS "")
  42. set(CMAKE_MODULE_LINKER_FLAGS "")
  43. set(CMAKE_SHARED_LINKER_FLAGS "")
  44. set(CMAKE_STATIC_LINKER_FLAGS "")
  45. set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
  46. set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}")
  47. set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}")
  48. set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}")
  49. set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}")
  50. set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}")
  51. set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}")
  52. set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}")
  53. endif()
  54. # Common utils
  55. include(GNUInstallDirs)
  56. include(CMake/Utils.cmake)
  57. # Additional Global Settings (add specific info there)
  58. include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
  59. # Use solution folders feature
  60. set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  61. # Source groups
  62. set(SOURCE_FILES
  63. jpegoptim.c
  64. jpegsrc.c
  65. jpegdest.c
  66. jpegmarker.c
  67. misc.c
  68. )
  69. source_group("Source Files" FILES ${SOURCE_FILES})
  70. # Target
  71. if(BUILD_FUZZERS)
  72. add_compile_definitions(BUILD_FOR_OSS_FUZZ=1)
  73. add_compile_options(-Wno-implicit-function-declaration)
  74. add_library(${PROJECT_NAME} ${SOURCE_FILES})
  75. target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
  76. # Temporarily remove fuzzing flags that would break compiler checks
  77. set(ORIG_C_FLAGS "${CMAKE_C_FLAGS}")
  78. string(REGEX REPLACE "-fsanitize=[^ ]+" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
  79. string(REGEX REPLACE "-fsanitize=[^ ]+" "" $ENV{CFLAGS} "${CMAKE_C_FLAGS}")
  80. else()
  81. add_executable(${PROJECT_NAME} ${SOURCE_FILES})
  82. endif()
  83. if(MSVC)
  84. use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
  85. set_target_properties(${PROJECT_NAME} PROPERTIES
  86. VS_GLOBAL_KEYWORD "Win32Proj"
  87. )
  88. endif()
  89. # Output directory
  90. if(MSVC)
  91. if(BUILD_NO_SUBFOLDERS)
  92. set(BINARY_OUTPUT_PATH ".")
  93. else()
  94. set(BINARY_OUTPUT_PATH "$<CONFIG>/${CMAKE_VS_PLATFORM_NAME}")
  95. endif()
  96. set_target_properties(${PROJECT_NAME} PROPERTIES
  97. RUNTIME_OUTPUT_DIRECTORY_DEBUG ${BINARY_OUTPUT_PATH}
  98. RUNTIME_OUTPUT_DIRECTORY_RELEASE ${BINARY_OUTPUT_PATH}
  99. )
  100. endif()
  101. # Interprocedural optimization (LTCG)
  102. set_target_properties(${PROJECT_NAME} PROPERTIES
  103. INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
  104. )
  105. if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  106. target_compile_options(${PROJECT_NAME} PUBLIC
  107. -fuse-linker-plugin
  108. )
  109. endif()
  110. # MSVC runtime library
  111. if(MSVC)
  112. get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
  113. string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
  114. $<$<CONFIG:Debug>:
  115. MultiThreadedDebug
  116. >
  117. $<$<CONFIG:Release>:
  118. MultiThreaded
  119. >
  120. $<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
  121. )
  122. set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
  123. endif()
  124. # Include directories
  125. #target_include_directories(${PROJECT_NAME} PUBLIC
  126. # "${CMAKE_CURRENT_SOURCE_DIR}"
  127. #)
  128. # Compile definitions
  129. target_compile_definitions(${PROJECT_NAME} PRIVATE
  130. "$<$<CONFIG:Debug>:"
  131. "_DEBUG;"
  132. "DEBUG"
  133. ">"
  134. "$<$<CONFIG:Release>:"
  135. "NDEBUG"
  136. ">"
  137. )
  138. if(MSVC)
  139. target_compile_definitions(${PROJECT_NAME} PRIVATE
  140. "WIN32;"
  141. "_WIN64;"
  142. "WIN64;"
  143. "_WINDOWS;"
  144. "UNICODE;"
  145. "_UNICODE"
  146. )
  147. endif()
  148. # Compile and link options
  149. if(MSVC)
  150. target_compile_options(${PROJECT_NAME} PRIVATE
  151. $<$<CONFIG:Debug>:
  152. /Od; # Disable optimization
  153. /RTC1 # Enable stack frame run-time error checking and reporting when a variable is used without having been initialized.
  154. >
  155. $<$<CONFIG:Release>:
  156. /MP; # Build with multiple processes
  157. /O2; # Optimize for speed
  158. /GF # Enable string pooling
  159. >
  160. /Gy; # Link per-function
  161. /W3; # Warning level
  162. /Zi; # Emit debug info in a separate PDB
  163. /TC; # Compile all source files as C source code regardless of extension
  164. /wd4996; # Suppress deprecation warnings
  165. ${DEFAULT_CXX_EXCEPTION_HANDLING};
  166. /GS; # Enable security checks against buffer overruns
  167. /Y- # Disable precompiled headers
  168. )
  169. target_link_options(${PROJECT_NAME} PRIVATE
  170. $<$<CONFIG:Debug>:
  171. /INCREMENTAL # Enable incremental linking (faster builds, larger filesize)
  172. >
  173. $<$<CONFIG:Release>:
  174. /OPT:REF; # Don't link unused functions
  175. /OPT:ICF; # Remove duplicate function definitions
  176. /INCREMENTAL:NO # Disable incremental linking
  177. >
  178. /MANIFEST; # Generate a manifest file
  179. /DEBUG:FULL; # Generate debugging symbols (in a separate PDB file)
  180. /MACHINE:${CMAKE_VS_PLATFORM_NAME};
  181. /SUBSYSTEM:CONSOLE; # Not a driver or GUI program
  182. /NXCOMPAT; # Support Windows Data Execution Prevention
  183. /DYNAMICBASE # Use address space layout randomization
  184. )
  185. # Link with setargv for command line wildcard support
  186. # See https://learn.microsoft.com/en-us/cpp/c-language/expanding-wildcard-arguments
  187. target_link_options(${PROJECT_NAME} PRIVATE
  188. setargv.obj
  189. )
  190. endif()
  191. # Header and function checks
  192. include(CheckIncludeFile)
  193. check_include_file(config.h HAVE_CONFIG_H)
  194. check_include_file(unistd.h HAVE_UNISTD_H)
  195. check_include_file(getopt.h HAVE_GETOPT_H)
  196. check_include_file(string.h HAVE_STRING_H)
  197. check_include_file(libgen.h HAVE_LIBGEN_H)
  198. check_include_file(math.h HAVE_MATH_H)
  199. check_include_file(fcntl.h HAVE_FCNTL_H)
  200. check_include_file(dirent.h HAVE_DIRENT_H)
  201. check_include_file(sys/stat.h HAVE_SYS_STAT_H)
  202. check_include_file(sys/types.h HAVE_SYS_TYPES_H)
  203. check_include_file(sys/wait.h HAVE_SYS_WAIT_H)
  204. include(CheckSymbolExists)
  205. check_symbol_exists(mkstemps "stdlib.h" HAVE_MKSTEMPS)
  206. check_symbol_exists(labs "stdlib.h" HAVE_LABS)
  207. check_symbol_exists(fileno "stdio.h" HAVE_FILENO)
  208. check_symbol_exists(utimensat "sys/stat.h" HAVE_UTIMENSAT)
  209. check_symbol_exists(fork "unistd.h" HAVE_FORK)
  210. check_symbol_exists(wait "sys/wait.h" HAVE_WAIT)
  211. check_symbol_exists(getopt "unistd.h" HAVE_GETOPT)
  212. check_symbol_exists(getopt_long "getopt.h" HAVE_GETOPT_LONG)
  213. include(CheckStructHasMember)
  214. if(HAVE_SYS_STAT_H)
  215. check_struct_has_member(
  216. "struct stat" st_mtim "sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C
  217. )
  218. endif()
  219. target_compile_definitions(${PROJECT_NAME} PRIVATE
  220. $<$<BOOL:${HAVE_CONFIG_H}>:HAVE_CONFIG_H>
  221. $<$<BOOL:${HAVE_UNISTD_H}>:HAVE_UNISTD_H>
  222. $<$<BOOL:${HAVE_GETOPT_H}>:HAVE_GETOPT_H>
  223. $<$<BOOL:${HAVE_STRING_H}>:HAVE_STRING_H>
  224. $<$<BOOL:${HAVE_LIBGEN_H}>:HAVE_LIBGEN_H>
  225. $<$<BOOL:${HAVE_MATH_H}>:HAVE_MATH_H>
  226. $<$<BOOL:${HAVE_FCNTL_H}>:HAVE_FCNTL_H>
  227. $<$<BOOL:${HAVE_DIRENT_H}>:HAVE_DIRENT_H>
  228. $<$<BOOL:${HAVE_SYS_STAT_H}>:HAVE_SYS_STAT_H>
  229. $<$<BOOL:${HAVE_SYS_TYPES_H}>:HAVE_SYS_TYPES_H>
  230. $<$<BOOL:${HAVE_SYS_WAIT_H}>:HAVE_SYS_WAIT_H>
  231. $<$<BOOL:${HAVE_MKSTEMPS}>:HAVE_MKSTEMPS>
  232. $<$<BOOL:${HAVE_LABS}>:HAVE_LABS>
  233. $<$<BOOL:${HAVE_FILENO}>:HAVE_FILENO>
  234. $<$<BOOL:${HAVE_UTIMENSAT}>:HAVE_UTIMENSAT>
  235. $<$<BOOL:${HAVE_FORK}>:HAVE_FORK>
  236. $<$<BOOL:${HAVE_WAIT}>:HAVE_WAIT>
  237. $<$<BOOL:${HAVE_GETOPT}>:HAVE_GETOPT>
  238. $<$<BOOL:${HAVE_GETOPT_LONG}>:HAVE_GETOPT_LONG>
  239. $<$<BOOL:${HAVE_STRUCT_STAT_ST_MTIM}>:HAVE_STRUCT_STAT_ST_MTIM>
  240. )
  241. # Include getopt only if no native implementation found.
  242. if(NOT HAVE_GETOPT_LONG)
  243. target_sources(${PROJECT_NAME} PRIVATE getopt.c getopt1.c)
  244. endif()
  245. # Attach a manifest file to support UTF-8 on compatible Windows systems (see https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page)
  246. if(MSVC)
  247. add_custom_command(
  248. TARGET ${PROJECT_NAME}
  249. POST_BUILD
  250. COMMAND "mt.exe" -nologo -manifest \"${CMAKE_CURRENT_SOURCE_DIR}/jpegoptim.manifest\" -outputresource:"${CMAKE_CURRENT_BINARY_DIR}/${BINARY_OUTPUT_PATH}/jpegoptim.exe"\;\#1
  251. COMMENT "Adding manifest..."
  252. )
  253. endif()
  254. # Dependencies
  255. if(USE_MOZJPEG)
  256. # Link with mozjpeg.
  257. # Version tree: https://github.com/mozilla/mozjpeg/tree/fd569212597dcc249752bd38ea58a4e2072da24f
  258. include(ExternalProject)
  259. if(WITH_ARITH)
  260. set(ARITH_FLAGS -DWITH_ARITH_DEC=1 -DWITH_ARITH_ENC=1)
  261. set(JPEGLIB_SUPPORTS_ARITH_CODE 1)
  262. endif()
  263. if (BUILD_FUZZERS)
  264. set(MOZJPEG_EXTENDED_CMAKE_FLAGS -DCMAKE_C_FLAGS="")
  265. else()
  266. set(MOZJPEG_EXTENDED_CMAKE_FLAGS "")
  267. endif()
  268. ExternalProject_Add(mozjpeg_lib
  269. GIT_REPOSITORY https://github.com/mozilla/mozjpeg.git
  270. GIT_TAG fd569212597dcc249752bd38ea58a4e2072da24f
  271. PREFIX ${CMAKE_CURRENT_BINARY_DIR}/mozjpeg
  272. CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/mozjpeg -DPNG_SUPPORTED=0 -DWITH_TURBOJPEG=0 -DENABLE_SHARED=0 ${ARITH_FLAGS} ${MOZJPEG_EXTENDED_CMAKE_FLAGS}
  273. )
  274. # Building and linking mozjpeg as a library, as explained here https://mirkokiefer.com/cmake-by-example-f95eb47d45b1
  275. ExternalProject_Get_Property(mozjpeg_lib install_dir)
  276. add_library(mozjpeg STATIC IMPORTED)
  277. if(MSVC)
  278. set_property(TARGET mozjpeg PROPERTY IMPORTED_LOCATION ${install_dir}/lib/jpeg-static.lib)
  279. else()
  280. target_link_libraries(mozjpeg INTERFACE m)
  281. set_property(TARGET mozjpeg PROPERTY IMPORTED_LOCATION ${install_dir}/lib/libjpeg.a)
  282. endif()
  283. add_dependencies(mozjpeg mozjpeg_lib)
  284. target_include_directories(${PROJECT_NAME} BEFORE PRIVATE ${install_dir}/include)
  285. target_link_libraries(${PROJECT_NAME} mozjpeg)
  286. add_dependencies(${PROJECT_NAME} mozjpeg)
  287. # Note: check_include_file, check_symbol_exists, check_struct_has_member, and check_c_source_compiles
  288. # cannot be used on ExternalProject dependencies because they are not compiled until build time, while check_*
  289. # functions run during the initial CMake configuration step.
  290. # Since the version is hardcoded above, feature checks may be set as constants as a workaround.
  291. set(HAVE_JINT_DC_SCAN_OPT_MODE 1)
  292. else()
  293. if(LIBJPEG_INCLUDE_DIR AND LIBJPEG_LIBRARY)
  294. # Link with custom libjpeg
  295. add_library(libjpeg STATIC IMPORTED)
  296. if(NOT MSVC)
  297. target_link_libraries(libjpeg INTERFACE m)
  298. endif()
  299. set_target_properties(libjpeg PROPERTIES IMPORTED_LOCATION ${LIBJPEG_LIBRARY})
  300. target_include_directories(${PROJECT_NAME} BEFORE PRIVATE ${LIBJPEG_INCLUDE_DIR})
  301. target_link_libraries(${PROJECT_NAME} libjpeg)
  302. add_dependencies(${PROJECT_NAME} libjpeg)
  303. else()
  304. # Link with system libjpeg
  305. include(FindJPEG)
  306. if(NOT JPEG_FOUND)
  307. message(FATAL_ERROR "Could not automatically locate libjpeg. Either specify -DUSE_MOZJPEG=1 to download and build with MozJPEG, or -DLIBJPEG_INCLUDE_DIR=... and -DLIBJPEG_LIBRARY=... to the appropriate paths to build with a custom libjpeg implementation.")
  308. endif()
  309. message(STATUS "Include dirs: ${JPEG_INCLUDE_DIRS}")
  310. target_include_directories(${PROJECT_NAME} PRIVATE ${JPEG_INCLUDE_DIRS})
  311. target_link_libraries(${PROJECT_NAME} JPEG::JPEG)
  312. endif()
  313. # Use all include directories and linked libraries as the main project for feature tests
  314. get_target_property(CMAKE_REQUIRED_LIBRARIES ${PROJECT_NAME} LINK_LIBRARIES)
  315. get_target_property(CMAKE_REQUIRED_INCLUDES ${PROJECT_NAME} INCLUDE_DIRECTORIES)
  316. # check_include_file, check_symbol_exists, and check_struct_has_member cannot be used with libjpeg.h
  317. # because libjpeg.h requires stdio.h to be included before it to not throw an unrelated compilation error.
  318. include(CheckCSourceCompiles)
  319. check_c_source_compiles(
  320. "
  321. #include <stdio.h>
  322. #include <jpeglib.h>
  323. int main(void)
  324. {
  325. return sizeof (&jpeg_read_header);
  326. }
  327. "
  328. HAVE_APPROPRIATE_LIBJPEG_VERSION
  329. )
  330. if(NOT HAVE_APPROPRIATE_LIBJPEG_VERSION)
  331. message(FATAL_ERROR "Invalid version: libjpeg version 6 or later is required.")
  332. endif()
  333. check_c_source_compiles(
  334. "
  335. #include <stdio.h>
  336. #include <jpeglib.h>
  337. METHODDEF(void) foo(void) {};
  338. int main(void)
  339. {
  340. return 0;
  341. }
  342. "
  343. WORKING_METHODDEF
  344. )
  345. if(NOT WORKING_METHODDEF)
  346. target_compile_definitions(${PROJECT_NAME} PRIVATE -DBROKEN_METHODDEF)
  347. endif()
  348. if(WITH_ARITH)
  349. # Check for arithmetic coding support
  350. check_c_source_compiles(
  351. "
  352. #include <stdio.h>
  353. #include <jpeglib.h>
  354. int main(void)
  355. {
  356. return sizeof (((struct jpeg_compress_struct *)0)->arith_code);
  357. }
  358. "
  359. JPEGLIB_SUPPORTS_ARITH_CODE
  360. )
  361. endif()
  362. # Check for MozJPEG's JINT_DC_SCAN_OPT_MODE extension
  363. check_c_source_compiles(
  364. "
  365. #include <stdio.h>
  366. #include <jpeglib.h>
  367. int main(void)
  368. {
  369. struct jpeg_compress_struct cinfo;
  370. if (jpeg_c_int_param_supported(&cinfo, JINT_DC_SCAN_OPT_MODE))
  371. jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 1);
  372. return 0;
  373. }
  374. "
  375. HAVE_JINT_DC_SCAN_OPT_MODE
  376. )
  377. endif()
  378. target_compile_definitions(${PROJECT_NAME} PRIVATE
  379. $<$<BOOL:${HAVE_JINT_DC_SCAN_OPT_MODE}>:HAVE_JINT_DC_SCAN_OPT_MODE>
  380. )
  381. if(WITH_ARITH AND JPEGLIB_SUPPORTS_ARITH_CODE)
  382. set(ARITH_ENABLED 1)
  383. target_compile_definitions(${PROJECT_NAME} PRIVATE -DHAVE_ARITH_CODE)
  384. endif()
  385. if(ARITH_ENABLED)
  386. message(STATUS "Arithmetic Coding: Enabled")
  387. else()
  388. message(STATUS "Arithmetic Coding: Disabled")
  389. endif()
  390. find_package(Python3 COMPONENTS Interpreter Development)
  391. if (Python3_FOUND)
  392. enable_testing()
  393. add_test(NAME unittests
  394. COMMAND ${Python3_EXECUTABLE} test.py
  395. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
  396. )
  397. set_property(TEST unittests PROPERTY ENVIRONMENT "JPEGOPTIM=$<TARGET_FILE:jpegoptim>" "DEBUG=1")
  398. endif()
  399. if (BUILD_FUZZERS AND DEFINED ENV{LIB_FUZZING_ENGINE})
  400. set(CMAKE_C_FLAGS "${ORIG_C_FLAGS}")
  401. add_subdirectory(fuzz)
  402. endif()
  403. install(TARGETS ${PROJECT_NAME})
  404. install(FILES jpegoptim.1 TYPE MAN)
  405. install(FILES README COPYRIGHT LICENSE TYPE DOC)