blob: 0ed37b2e44caf234584bb0d61dffaef2f12d1443 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001--- /dev/null
2+++ b/CMakeLists.txt
3@@ -0,0 +1,354 @@
4+cmake_minimum_required(VERSION 3.12)
5+
6+project(bzip2
7+ VERSION 1.0.8
8+ DESCRIPTION "This Bzip2/libbz2 a program and library for lossless block-sorting data compression."
9+ LANGUAGES C)
10+
11+# See versioning rule:
12+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
13+#
14+# KEEP THESE IN SYNC WITH meson.build OR STUFF WILL BREAK!
15+set(LT_CURRENT 1)
16+set(LT_REVISION 8)
17+set(LT_AGE 0)
18+
19+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
20+
21+include_directories(${PROJECT_BINARY_DIR})
22+
23+math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
24+set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}")
25+set(PACKAGE_VERSION ${PROJECT_VERSION})
26+
27+set(ENABLE_APP_DEFAULT ON)
28+set(ENABLE_EXAMPLES_DEFAULT OFF)
29+set(ENABLE_DOCS_DEFAULT OFF)
30+include(CMakeOptions.txt)
31+
32+if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_EXAMPLES))
33+ # Remember when disabled options are disabled for later diagnostics.
34+ set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1)
35+else()
36+ set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0)
37+endif()
38+if(ENABLE_LIB_ONLY)
39+ set(ENABLE_APP OFF)
40+ set(ENABLE_EXAMPLES OFF)
41+endif()
42+
43+# Do not disable assertions based on CMAKE_BUILD_TYPE.
44+foreach(_build_type Release MinSizeRel RelWithDebInfo)
45+ foreach(_lang C)
46+ string(TOUPPER CMAKE_${_lang}_FLAGS_${_build_type} _var)
47+ string(REGEX REPLACE "(^|)[/-]D *NDEBUG($|)" " " ${_var} "${${_var}}")
48+ endforeach()
49+endforeach()
50+
51+# Support the latest c++ standard available.
52+include(CheckCCompilerFlag)
53+include(CheckCXXCompilerFlag)
54+
55+function(extract_valid_c_flags varname)
56+ set(valid_flags)
57+ foreach(flag IN LISTS ARGN)
58+ string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
59+ set(flag_var "C_FLAG_${flag_var}")
60+ check_c_compiler_flag("${flag}" "${flag_var}")
61+ if(${flag_var})
62+ set(valid_flags "${valid_flags} ${flag}")
63+ endif()
64+ endforeach()
65+ set(${varname} "${valid_flags}" PARENT_SCOPE)
66+endfunction()
67+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
68+ set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE)
69+
70+ # Include "None" as option to disable any additional (optimization) flags,
71+ # relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by
72+ # default). These strings are presented in cmake-gui.
73+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
74+ None Debug Release MinSizeRel RelWithDebInfo)
75+endif()
76+
77+# Install a symlink of script to the "bin" directory.
78+# Not intended for use on Windows.
79+function(install_script_symlink original symlink)
80+ add_custom_command(OUTPUT ${symlink}
81+ COMMAND ${CMAKE_COMMAND} -E create_symlink ${original} ${symlink}
82+ DEPENDS ${original}
83+ COMMENT "Generating symbolic link ${symlink} of ${original}")
84+ add_custom_target(${symlink}_tgt ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${symlink})
85+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${symlink} DESTINATION ${CMAKE_INSTALL_BINDIR})
86+endfunction()
87+
88+# Install a symlink of binary target to the "bin" directory.
89+# On Windows, it will be a copy instead of a symlink.
90+function(install_target_symlink original symlink)
91+ if(WIN32)
92+ set(op copy)
93+ set(symlink "${symlink}.exe")
94+ else()
95+ set(op create_symlink)
96+ endif()
97+ add_custom_command(TARGET ${original} POST_BUILD
98+ COMMAND ${CMAKE_COMMAND} -E ${op} $<TARGET_FILE_NAME:${original}> ${symlink}
99+ WORKING_DIRECTORY $<TARGET_FILE_DIR:${original}>
100+ COMMENT "Generating symbolic link (or copy) ${symlink} of ${original}")
101+ install(PROGRAMS $<TARGET_FILE_DIR:${original}>/${symlink} DESTINATION ${CMAKE_INSTALL_BINDIR})
102+endfunction()
103+
104+include(GNUInstallDirs)
105+
106+# Checks for header files.
107+include(CheckIncludeFile)
108+check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
109+check_include_file(fcntl.h HAVE_FCNTL_H)
110+check_include_file(inttypes.h HAVE_INTTYPES_H)
111+check_include_file(limits.h HAVE_LIMITS_H)
112+check_include_file(netdb.h HAVE_NETDB_H)
113+check_include_file(netinet/in.h HAVE_NETINET_IN_H)
114+check_include_file(pwd.h HAVE_PWD_H)
115+check_include_file(sys/socket.h HAVE_SYS_SOCKET_H)
116+check_include_file(sys/time.h HAVE_SYS_TIME_H)
117+check_include_file(syslog.h HAVE_SYSLOG_H)
118+check_include_file(time.h HAVE_TIME_H)
119+check_include_file(unistd.h HAVE_UNISTD_H)
120+
121+include(CheckTypeSize)
122+# Checks for typedefs, structures, and compiler characteristics.
123+# AC_TYPE_SIZE_T
124+check_type_size("ssize_t" SIZEOF_SSIZE_T)
125+if(NOT SIZEOF_SSIZE_T)
126+ # ssize_t is a signed type in POSIX storing at least -1.
127+ # Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools).
128+ set(ssize_t int)
129+endif()
130+
131+include(CheckStructHasMember)
132+check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
133+
134+include(CheckSymbolExists)
135+# XXX does this correctly detect initgroups (un)availability on cygwin?
136+check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
137+if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
138+ # FreeBSD declares initgroups() in unistd.h
139+ check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2)
140+ if(HAVE_DECL_INITGROUPS2)
141+ set(HAVE_DECL_INITGROUPS 1)
142+ endif()
143+endif()
144+
145+set(WARNCFLAGS)
146+if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
147+ if(ENABLE_WERROR)
148+ set(WARNCFLAGS /WX)
149+ endif()
150+else()
151+ if(ENABLE_WERROR)
152+ extract_valid_c_flags(WARNCFLAGS -Werror)
153+ endif()
154+
155+ # For C compiler
156+ # Please keep this list in sync with meson.build
157+ extract_valid_c_flags(WARNCFLAGS
158+ -Wall
159+ -Wextra
160+ -Wmissing-prototypes
161+ -Wstrict-prototypes
162+ -Wmissing-declarations
163+ -Wpointer-arith
164+ -Wdeclaration-after-statement
165+ -Wformat-security
166+ -Wwrite-strings
167+ -Wshadow
168+ -Winline
169+ -Wnested-externs
170+ -Wfloat-equal
171+ -Wundef
172+ -Wendif-labels
173+ -Wempty-body
174+ -Wcast-align
175+ -Wclobbered
176+ -Wvla
177+ -Wpragmas
178+ -Wunreachable-code
179+ -Waddress
180+ -Wattributes
181+ -Wdiv-by-zero
182+ -Wshorten-64-to-32
183+ -Wconversion
184+ -Wextended-offsetof
185+ -Wformat-nonliteral
186+ -Wlanguage-extension-token
187+ -Wmissing-field-initializers
188+ -Wmissing-noreturn
189+ -Wmissing-variable-declarations
190+ # -Wpadded # Not used because we cannot change public structs
191+ -Wsign-conversion
192+ # -Wswitch-enum # Not used because this basically disallows default case
193+ -Wunreachable-code-break
194+ -Wunused-macros
195+ -Wunused-parameter
196+ -Wredundant-decls
197+ -Wheader-guard
198+ -Wno-format-nonliteral # This is required because we pass format string as "const char*.
199+ )
200+endif()
201+
202+if(ENABLE_DEBUG)
203+ set(DEBUGBUILD 1)
204+endif()
205+
206+#add_definitions(-DHAVE_CONFIG_H)
207+#configure_file(cmakeconfig.h.in config.h)
208+
209+# autotools-compatible names
210+# Sphinx expects relative paths in the .rst files. Use the fact that the files
211+# below are all one directory level deep.
212+file(RELATIVE_PATH top_srcdir ${CMAKE_CURRENT_BINARY_DIR}/dir ${CMAKE_CURRENT_SOURCE_DIR})
213+file(RELATIVE_PATH top_builddir ${CMAKE_CURRENT_BINARY_DIR}/dir ${CMAKE_CURRENT_BINARY_DIR})
214+set(abs_top_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
215+set(abs_top_builddir ${CMAKE_CURRENT_BINARY_DIR})
216+# bzip2.pc (pkg-config file)
217+set(prefix ${CMAKE_INSTALL_PREFIX})
218+set(exec_prefix ${CMAKE_INSTALL_PREFIX})
219+set(bindir ${CMAKE_INSTALL_FULL_BINDIR})
220+set(sbindir ${CMAKE_INSTALL_FULL_SBINDIR})
221+set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
222+set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
223+set(VERSION ${PACKAGE_VERSION})
224+
225+#
226+# The build targets.
227+# In a larger project, the following would be in subdirectories and
228+# These targets would be included with `add_subdirectory()`
229+#
230+set(BZ2_SOURCES
231+ blocksort.c
232+ huffman.c
233+ crctable.c
234+ randtable.c
235+ compress.c
236+ decompress.c
237+ bzlib.c)
238+
239+# The bz2 OBJECT-library, required for bzip2, bzip2recover.
240+add_library(bz2_ObjLib OBJECT)
241+target_sources(bz2_ObjLib
242+ PRIVATE ${BZ2_SOURCES}
243+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h
244+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h)
245+
246+if(ENABLE_SHARED_LIB)
247+ # The libbz2 shared library.
248+ add_library(bz2 SHARED ${BZ2_RES})
249+ target_sources(bz2
250+ PRIVATE ${BZ2_SOURCES}
251+ ${CMAKE_CURRENT_SOURCE_DIR}/libbz2.def
252+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h
253+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h)
254+ # Always use '-fPIC'/'-fPIE' option for shared libraries.
255+ set_property(TARGET bz2 PROPERTY POSITION_INDEPENDENT_CODE ON)
256+ set_target_properties(bz2 PROPERTIES
257+ COMPILE_FLAGS "${WARNCFLAGS}"
258+ VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION})
259+ install(TARGETS bz2 DESTINATION ${CMAKE_INSTALL_LIBDIR})
260+ install(FILES bzlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
261+
262+ if(USE_OLD_SONAME)
263+ # Hack to support the old libbz2.so.1.0 version by including an extra copy.
264+ # Technically the old SONAME is not libtool compatible.
265+ # This hack is to support binary compatibility with libbz2 in some distro packages.
266+ if(UNIX AND NOT APPLE)
267+ add_library(bz2_old_soname SHARED ${BZ2_RES})
268+ target_sources(bz2_old_soname
269+ PRIVATE ${BZ2_SOURCES}
270+ ${CMAKE_CURRENT_SOURCE_DIR}/libbz2.def
271+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h
272+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h
273+ )
274+ set_target_properties(bz2_old_soname PROPERTIES
275+ COMPILE_FLAGS "${WARNCFLAGS}"
276+ VERSION ${LT_SOVERSION}.${LT_AGE} SOVERSION ${LT_SOVERSION}.${LT_AGE}
277+ OUTPUT_NAME bz2
278+ )
279+ install(TARGETS bz2_old_soname DESTINATION ${CMAKE_INSTALL_LIBDIR})
280+ endif()
281+ endif()
282+endif()
283+
284+if(ENABLE_STATIC_LIB)
285+ # The libbz2 static library.
286+ add_library(bz2_static STATIC)
287+ target_sources(bz2_static
288+ PRIVATE ${BZ2_SOURCES}
289+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h
290+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h)
291+ set_target_properties(bz2_static PROPERTIES
292+ COMPILE_FLAGS "${WARNCFLAGS}"
293+ VERSION ${LT_VERSION}
294+ SOVERSION ${LT_SOVERSION}
295+ ARCHIVE_OUTPUT_NAME bz2_static)
296+ target_compile_definitions(bz2_static PUBLIC BZ2_STATICLIB)
297+ install(TARGETS bz2_static DESTINATION ${CMAKE_INSTALL_LIBDIR})
298+ install(FILES bzlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
299+endif()
300+
301+if(ENABLE_APP)
302+ # The bzip2 executable.
303+ add_executable(bzip2)
304+ target_sources(bzip2
305+ PRIVATE bzip2.c)
306+ target_link_libraries(bzip2
307+ PRIVATE bz2_ObjLib)
308+ if(WIN32)
309+ target_compile_definitions(bzip2 PUBLIC BZ_LCCWIN32 BZ_UNIX=0)
310+ else()
311+ target_compile_definitions(bzip2 PUBLIC BZ_LCCWIN32=0 BZ_UNIX)
312+ endif()
313+ install(TARGETS bzip2 DESTINATION ${CMAKE_INSTALL_BINDIR})
314+
315+ # Create bzip2 copies bzcat and bunzip.
316+ # The default behavior is altered in bzip2.c code by checking the program name.
317+ install_target_symlink(bzip2 bzcat)
318+ install_target_symlink(bzip2 bunzip)
319+
320+ # The bzip2recover executable.
321+ add_executable(bzip2recover)
322+ target_sources(bzip2recover
323+ PRIVATE bzip2recover.c)
324+ target_link_libraries(bzip2recover
325+ PRIVATE bz2_ObjLib)
326+ if(WIN32)
327+ target_compile_definitions(bzip2recover PUBLIC BZ_LCCWIN32 BZ_UNIX=0)
328+ else()
329+ target_compile_definitions(bzip2recover PUBLIC BZ_LCCWIN32=0 BZ_UNIX)
330+ endif()
331+ install(TARGETS bzip2recover DESTINATION ${CMAKE_INSTALL_BINDIR})
332+
333+ if(ENABLE_EXAMPLES)
334+ if(ENABLE_SHARED_LIB)
335+ # The dlltest executable.
336+ add_executable(dlltest)
337+ target_sources(dlltest
338+ PRIVATE dlltest.c)
339+ target_link_libraries(dlltest bz2)
340+ install(TARGETS dlltest DESTINATION ${CMAKE_INSTALL_BINDIR})
341+ endif()
342+ endif()
343+
344+ if(NOT WIN32)
345+ # Install shell scripts, and renamed copies.
346+ install(PROGRAMS bzdiff bzgrep bzmore
347+ DESTINATION ${CMAKE_INSTALL_BINDIR})
348+
349+ install_script_symlink(bzdiff bzcmp)
350+
351+ install_script_symlink(bzgrep bzegrep)
352+ install_script_symlink(bzgrep bzfgrep)
353+
354+ install_script_symlink(bzmore bzless)
355+ endif()
356+
357+endif()
358--- /dev/null
359+++ b/CMakeOptions.txt
360@@ -0,0 +1,22 @@
361+# Features that can be enabled for cmake (see CMakeLists.txt)
362+
363+option(ENABLE_WERROR "Turn on compile time warnings")
364+
365+option(ENABLE_DEBUG "Turn on debug output")
366+
367+option(ENABLE_APP "Build applications (bzip2, and bzip2recover)"
368+ ${ENABLE_APP_DEFAULT})
369+
370+option(ENABLE_DOCS "Generate documentation"
371+ ${ENABLE_DOCS_DEFAULT})
372+
373+option(ENABLE_EXAMPLES "Build examples"
374+ ${ENABLE_EXAMPLES_DEFAULT})
375+
376+option(ENABLE_LIB_ONLY "Build libbz2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0")
377+
378+option(ENABLE_STATIC_LIB "Build libbz2 in static mode also")
379+
380+option(ENABLE_SHARED_LIB "Build libbz2 as a shared library" ON)
381+
382+option(USE_OLD_SONAME "Use libbz2.so.1.0 for compatibility with old Makefiles" OFF)