1# CMake support for LZ4
2#
3# To the extent possible under law, the author(s) have dedicated all
4# copyright and related and neighboring rights to this software to
5# the public domain worldwide. This software is distributed without
6# any warranty.
7#
8# For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
9#
10# LZ4's CMake support is maintained by Evan Nemerson; when filing
11# bugs please mention @nemequ to make sure I see it.
12
13set(LZ4_TOP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
14
15option(LZ4_BUILD_LEGACY_LZ4C "Build lz4c progam with legacy argument support" ON)
16
17# Parse version information
18file(STRINGS "${LZ4_TOP_SOURCE_DIR}/lib/lz4.h" LZ4_VERSION_MAJOR REGEX "^#define LZ4_VERSION_MAJOR +([0-9]+) +.*$")
19string(REGEX REPLACE "^#define LZ4_VERSION_MAJOR +([0-9]+) +.*$" "\\1" LZ4_VERSION_MAJOR "${LZ4_VERSION_MAJOR}")
20file(STRINGS "${LZ4_TOP_SOURCE_DIR}/lib/lz4.h" LZ4_VERSION_MINOR REGEX "^#define LZ4_VERSION_MINOR +([0-9]+) +.*$")
21string(REGEX REPLACE "^#define LZ4_VERSION_MINOR +([0-9]+) +.*$" "\\1" LZ4_VERSION_MINOR "${LZ4_VERSION_MINOR}")
22file(STRINGS "${LZ4_TOP_SOURCE_DIR}/lib/lz4.h" LZ4_VERSION_RELEASE REGEX "^#define LZ4_VERSION_RELEASE +([0-9]+) +.*$")
23string(REGEX REPLACE "^#define LZ4_VERSION_RELEASE +([0-9]+) +.*$" "\\1" LZ4_VERSION_RELEASE "${LZ4_VERSION_RELEASE}")
24set(LZ4_VERSION_STRING "${LZ4_VERSION_MAJOR}.${LZ4_VERSION_MINOR}.${LZ4_VERSION_RELEASE}")
25mark_as_advanced(LZ4_VERSION_STRING LZ4_VERSION_MAJOR LZ4_VERSION_MINOR LZ4_VERSION_RELEASE)
26
27if("${CMAKE_VERSION}" VERSION_LESS "3.0")
28  project(LZ4 C)
29else()
30  cmake_policy (SET CMP0048 NEW)
31  project(LZ4
32    VERSION ${LZ4_VERSION_STRING}
33    LANGUAGES C)
34endif()
35
36cmake_minimum_required (VERSION 2.8.6)
37
38# If LZ4 is being bundled in another project, we don't want to
39# install anything.  However, we want to let people override this, so
40# we'll use the LZ4_BUNDLED_MODE variable to let them do that; just
41# set it to OFF in your project before you add_subdirectory(lz4/contrib/cmake_unofficial).
42get_directory_property(LZ4_PARENT_DIRECTORY PARENT_DIRECTORY)
43if("${LZ4_BUNDLED_MODE}" STREQUAL "")
44  # Bundled mode hasn't been set one way or the other, set the default
45  # depending on whether or not we are the top-level project.
46  if("${LZ4_PARENT_DIRECTORY}" STREQUAL "")
47    set(LZ4_BUNDLED_MODE OFF)
48  else()
49    set(LZ4_BUNDLED_MODE ON)
50  endif()
51endif()
52mark_as_advanced(LZ4_BUNDLED_MODE)
53
54# CPack
55if(NOT LZ4_BUNDLED_MODE AND NOT CPack_CMake_INCLUDED)
56  set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LZ4 compression library")
57  set(CPACK_PACKAGE_DESCRIPTION_FILE "${LZ4_TOP_SOURCE_DIR}/README.md")
58  set(CPACK_RESOURCE_FILE_LICENSE "${LZ4_TOP_SOURCE_DIR}/LICENSE")
59  set(CPACK_PACKAGE_VERSION_MAJOR ${LZ4_VERSION_MAJOR})
60  set(CPACK_PACKAGE_VERSION_MINOR ${LZ4_VERSION_MINOR})
61  set(CPACK_PACKAGE_VERSION_PATCH ${LZ4_VERSION_RELEASE})
62  include(CPack)
63endif(NOT LZ4_BUNDLED_MODE AND NOT CPack_CMake_INCLUDED)
64
65# Allow people to choose whether to build shared or static libraries
66# via the BUILD_SHARED_LIBS option unless we are in bundled mode, in
67# which case we always use static libraries.
68include(CMakeDependentOption)
69CMAKE_DEPENDENT_OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON "NOT LZ4_BUNDLED_MODE" OFF)
70CMAKE_DEPENDENT_OPTION(BUILD_STATIC_LIBS "Build static libraries" OFF "BUILD_SHARED_LIBS" ON)
71
72if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
73  message(FATAL_ERROR "Both BUILD_SHARED_LIBS and BUILD_STATIC_LIBS have been disabled")
74endif()
75
76set(LZ4_LIB_SOURCE_DIR "${LZ4_TOP_SOURCE_DIR}/lib")
77set(LZ4_PROG_SOURCE_DIR "${LZ4_TOP_SOURCE_DIR}/programs")
78
79include_directories("${LZ4_LIB_SOURCE_DIR}")
80
81# CLI sources
82set(LZ4_SOURCES
83  "${LZ4_LIB_SOURCE_DIR}/lz4.c"
84  "${LZ4_LIB_SOURCE_DIR}/lz4hc.c"
85  "${LZ4_LIB_SOURCE_DIR}/lz4.h"
86  "${LZ4_LIB_SOURCE_DIR}/lz4hc.h"
87  "${LZ4_LIB_SOURCE_DIR}/lz4frame.c"
88  "${LZ4_LIB_SOURCE_DIR}/lz4frame.h"
89  "${LZ4_LIB_SOURCE_DIR}/xxhash.c")
90set(LZ4_CLI_SOURCES
91  "${LZ4_PROG_SOURCE_DIR}/bench.c"
92  "${LZ4_PROG_SOURCE_DIR}/lz4cli.c"
93  "${LZ4_PROG_SOURCE_DIR}/lz4io.c"
94  "${LZ4_PROG_SOURCE_DIR}/datagen.c")
95
96# Whether to use position independent code for the static library.  If
97# we're building a shared library this is ignored and PIC is always
98# used.
99option(LZ4_POSITION_INDEPENDENT_LIB "Use position independent code for static library (if applicable)" ON)
100
101# liblz4
102set(LZ4_LIBRARIES_BUILT)
103if(BUILD_SHARED_LIBS)
104  add_library(lz4_shared SHARED ${LZ4_SOURCES})
105  set_target_properties(lz4_shared PROPERTIES
106    OUTPUT_NAME lz4
107    SOVERSION "${LZ4_VERSION_MAJOR}"
108    VERSION "${LZ4_VERSION_STRING}")
109  list(APPEND LZ4_LIBRARIES_BUILT lz4_shared)
110endif()
111if(BUILD_STATIC_LIBS)
112  add_library(lz4_static STATIC ${LZ4_SOURCES})
113  set_target_properties(lz4_static PROPERTIES
114    OUTPUT_NAME lz4
115    POSITION_INDEPENDENT_CODE ${LZ4_POSITION_INDEPENDENT_LIB})
116  list(APPEND LZ4_LIBRARIES_BUILT lz4_static)
117endif()
118
119# link to shared whenever possible, to static otherwise
120if(BUILD_SHARED_LIBS)
121  set(LZ4_LINK_LIBRARY lz4_shared)
122else()
123  set(LZ4_LINK_LIBRARY lz4_static)
124endif()
125
126# lz4
127set(LZ4_PROGRAMS_BUILT lz4cli)
128add_executable(lz4cli ${LZ4_CLI_SOURCES})
129set_target_properties(lz4cli PROPERTIES OUTPUT_NAME lz4)
130target_link_libraries(lz4cli ${LZ4_LINK_LIBRARY})
131
132# lz4c
133if (LZ4_BUILD_LEGACY_LZ4C)
134  list(APPEND LZ4_PROGRAMS_BUILT lz4c)
135  add_executable(lz4c ${LZ4_CLI_SOURCES})
136  set_target_properties(lz4c PROPERTIES COMPILE_DEFINITIONS "ENABLE_LZ4C_LEGACY_OPTIONS")
137  target_link_libraries(lz4c ${LZ4_LINK_LIBRARY})
138endif()
139
140# Extra warning flags
141include (CheckCCompilerFlag)
142foreach (flag
143    # GCC-style
144    -Wall
145    -Wextra
146    -Wundef
147    -Wcast-qual
148    -Wcast-align
149    -Wshadow
150    -Wswitch-enum
151    -Wdeclaration-after-statement
152    -Wstrict-prototypes
153    -Wpointer-arith
154
155    # MSVC-style
156    /W4)
157  # Because https://gcc.gnu.org/wiki/FAQ#wnowarning
158  string(REGEX REPLACE "\\-Wno\\-(.+)" "-W\\1" flag_to_test "${flag}")
159  string(REGEX REPLACE "[^a-zA-Z0-9]+" "_" test_name "CFLAG_${flag_to_test}")
160
161  check_c_compiler_flag("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${test_name})
162
163  if(${test_name})
164    set(CMAKE_C_FLAGS "${flag} ${CMAKE_C_FLAGS}")
165  endif()
166
167  unset(test_name)
168  unset(flag_to_test)
169endforeach (flag)
170
171if(NOT LZ4_BUNDLED_MODE)
172  include(GNUInstallDirs)
173
174  install(TARGETS ${LZ4_PROGRAMS_BUILT}
175    BUNDLE	DESTINATION "${CMAKE_INSTALL_BINDIR}"
176    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
177  install(TARGETS ${LZ4_LIBRARIES_BUILT}
178    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
179    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
180    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
181  install(FILES
182    "${LZ4_LIB_SOURCE_DIR}/lz4.h"
183    "${LZ4_LIB_SOURCE_DIR}/lz4frame.h"
184    "${LZ4_LIB_SOURCE_DIR}/lz4hc.h"
185    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
186  install(FILES "${LZ4_PROG_SOURCE_DIR}/lz4.1"
187    DESTINATION "${CMAKE_INSTALL_MANDIR}/man1")
188  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/liblz4.pc"
189    DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
190
191  # install lz4cat and unlz4 symlinks on *nix
192  if(UNIX)
193    install(CODE "
194      foreach(f lz4cat unlz4)
195        set(dest \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/\${f}\")
196        message(STATUS \"Symlinking: \${dest} -> lz4\")
197        execute_process(
198          COMMAND \"${CMAKE_COMMAND}\" -E create_symlink lz4 \"\${dest}\")
199      endforeach()
200    ")
201
202    # create manpage aliases
203    foreach(f lz4cat unlz4)
204      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${f}.1" ".so man1/lz4.1\n")
205      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${f}.1"
206        DESTINATION "${CMAKE_INSTALL_MANDIR}/man1")
207    endforeach()
208  endif(UNIX)
209endif(NOT LZ4_BUNDLED_MODE)
210
211# pkg-config
212set(PREFIX "${CMAKE_INSTALL_PREFIX}")
213
214if("${CMAKE_INSTALL_FULL_LIBDIR}" STREQUAL "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
215  set(LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
216else()
217  set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")
218endif()
219
220if("${CMAKE_INSTALL_FULL_INCLUDEDIR}" STREQUAL "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
221  set(INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
222else()
223  set(INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
224endif()
225
226# for liblz4.pc substitution
227set(VERSION ${LZ4_VERSION_STRING})
228configure_file(${LZ4_LIB_SOURCE_DIR}/liblz4.pc.in liblz4.pc @ONLY)
229