1PROJECT(libucl C)
2CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
3
4SET(LIBUCL_VERSION_MAJOR 0)
5SET(LIBUCL_VERSION_MINOR 5)
6SET(LIBUCL_VERSION_PATCH 0)
7
8SET(LIBUCL_VERSION
9        "${LIBUCL_VERSION_MAJOR}.${LIBUCL_VERSION_MINOR}.${LIBUCL_VERSION_PATCH}")
10
11INCLUDE(CheckCCompilerFlag)
12INCLUDE(CheckCSourceCompiles)
13INCLUDE(FindOpenSSL)
14INCLUDE(GNUInstallDirs)
15
16OPTION(ENABLE_URL_INCLUDE  "Enable urls in ucl includes (requires libcurl or libfetch) [default: OFF]" OFF)
17OPTION(ENABLE_URL_SIGN  "Enable signatures check in ucl includes (requires openssl) [default: OFF]" OFF)
18OPTION(BUILD_SHARED_LIBS "Build Shared Libraries [default: OFF]" OFF)
19OPTION(ENABLE_LUA "Enable lua support [default: OFF]" OFF)
20OPTION(ENABLE_LUAJIT "Enable luajit support [default: OFF]" OFF)
21OPTION(ENABLE_UTILS "Enable building utility binaries [default: OFF]" OFF)
22
23# Find lua installation
24MACRO(FindLua)
25	# Find lua libraries
26	UNSET(LUA_INCLUDE_DIR CACHE)
27	UNSET(LUA_LIBRARY CACHE)
28	CMAKE_PARSE_ARGUMENTS(LUA "" "VERSION_MAJOR;VERSION_MINOR;ROOT" "" ${ARGN})
29
30	IF(NOT LUA_VERSION_MAJOR OR NOT LUA_VERSION_MINOR)
31		MESSAGE(FATAL_ERROR "Invalid FindLua invocation: ${ARGN}")
32	ENDIF()
33
34	IF(ENABLE_LUAJIT MATCHES "ON")
35		MESSAGE(STATUS "Check for luajit ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
36		FIND_PATH(LUA_INCLUDE_DIR luajit.h
37				HINTS
38				"${RSPAMD_SEARCH_PATH}" "${LUA_ROOT}"
39				$ENV{LUA_DIR}
40				PATH_SUFFIXES "include/luajit-2.0"
41				"include/luajit${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
42				"include/luajit${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
43				"include/luajit-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
44				"include/luajit"
45				"include/lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
46				"include/lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
47				"include/lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
48				include/lua include
49				PATHS ${RSPAMD_DEFAULT_INCLUDE_PATHS}
50		)
51		FIND_LIBRARY(LUA_LIBRARY
52				NAMES luajit
53				"luajit-2.0"
54				"luajit2.0"
55				"luajit${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
56				"luajit${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
57				"luajit-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
58				HINTS
59				"${RSPAMD_SEARCH_PATH}" "${LUA_ROOT}"
60				$ENV{LUA_DIR}
61				PATH_SUFFIXES lib64 lib
62				PATHS ${RSPAMD_DEFAULT_LIBRARY_PATHS}
63				DOC "Lua library"
64		)
65
66		IF(NOT LUA_LIBRARY OR NOT LUA_INCLUDE_DIR)
67			MESSAGE(STATUS "Fallback from luajit to plain lua")
68			SET(ENABLE_LUAJIT "OFF")
69			MESSAGE(STATUS "Check for lua ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
70			FIND_PATH(LUA_INCLUDE_DIR lua.h
71					HINTS
72					"${RSPAMD_SEARCH_PATH}" "${LUA_ROOT}"
73					$ENV{LUA_DIR}
74					PATH_SUFFIXES "include/lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
75					"include/lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
76					"include/lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
77					include/lua include
78					PATHS ${RSPAMD_DEFAULT_INCLUDE_PATHS}
79			)
80			FIND_LIBRARY(LUA_LIBRARY
81					NAMES lua
82					"lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
83					"lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
84					"lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
85					HINTS
86					"${RSPAMD_SEARCH_PATH}" "${LUA_ROOT}"
87					$ENV{LUA_DIR}
88					PATH_SUFFIXES lib64 lib
89					PATHS ${RSPAMD_DEFAULT_LIBRARY_PATHS}
90					DOC "Lua library"
91			)
92		ENDIF()
93	ELSE(ENABLE_LUAJIT MATCHES "ON")
94		MESSAGE(STATUS "Check for lua ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
95		FIND_PATH(LUA_INCLUDE_DIR lua.h
96				HINTS
97				"${RSPAMD_SEARCH_PATH}" "${LUA_ROOT}"
98				$ENV{LUA_DIR}
99				PATH_SUFFIXES "include/lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
100				"include/lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
101				"include/lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
102				include/lua include
103				PATHS ${RSPAMD_DEFAULT_INCLUDE_PATHS}
104		)
105		FIND_LIBRARY(LUA_LIBRARY
106				NAMES lua
107				"lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}"
108				"lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
109				"lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}"
110				HINTS
111				"${RSPAMD_SEARCH_PATH}" "${LUA_ROOT}"
112				$ENV{LUA_DIR}
113				PATH_SUFFIXES lib64 lib
114				PATHS ${RSPAMD_DEFAULT_LIBRARY_PATHS}
115				DOC "Lua library"
116		)
117	ENDIF(ENABLE_LUAJIT MATCHES "ON")
118
119	IF(LUA_LIBRARY AND LUA_INCLUDE_DIR)
120		SET(LUA_FOUND 1)
121		IF(NOT LUA_VERSION_MAJOR OR NOT LUA_VERSION_MINOR)
122			SET(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR})
123			SET(LUA_VERSION_MINOR ${LUA_VERSION_MINOR})
124		ENDIF(NOT LUA_VERSION_MAJOR OR NOT LUA_VERSION_MINOR)
125		IF(ENABLE_LUAJIT MATCHES "ON")
126			MESSAGE(STATUS "Found luajit ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
127		ELSE(ENABLE_LUAJIT MATCHES "ON")
128			MESSAGE(STATUS "Found lua ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
129		ENDIF(ENABLE_LUAJIT MATCHES "ON")
130	ENDIF(LUA_LIBRARY AND LUA_INCLUDE_DIR)
131ENDMACRO()
132
133IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
134	LIST(APPEND CMAKE_REQUIRED_LIBRARIES rt)
135ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
136
137IF(ENABLE_URL_INCLUDE MATCHES "ON")
138    FIND_LIBRARY(LIBFETCH_LIBRARY NAMES fetch PATHS	PATH_SUFFIXES lib64 lib
139                      PATHS
140                          ~/Library/Frameworks
141                          /Library/Frameworks
142                          /usr/local
143                          /usr
144                          /sw
145                          /opt/local
146                          /opt/csw
147                          /opt
148                     DOC "Path where the libfetch library can be found")
149    IF(LIBFETCH_LIBRARY)
150    	FIND_FILE(HAVE_FETCH_H NAMES fetch.h PATHS /usr/include
151    											   /opt/include
152    											   /usr/local/include
153    				DOC "Path to libfetch header")
154    ELSE(LIBFETCH_LIBRARY)
155    	# Try to find libcurl
156        FIND_PACKAGE(CURL)
157    	IF(NOT CURL_FOUND)
158    		MESSAGE(WARNING "Neither libcurl nor libfetch were found, no support of URL includes in configuration")
159    	ENDIF(NOT CURL_FOUND)
160    ENDIF(LIBFETCH_LIBRARY)
161ENDIF(ENABLE_URL_INCLUDE MATCHES "ON")
162
163set(SYNC_BUILTINS_TEST_SOURCE [====[
164int main()
165{
166    unsigned long val;
167
168    __sync_bool_compare_and_swap(&val, 0, 1);
169    __sync_add_and_fetch(&val, 1);
170    __sync_fetch_and_add(&val, 0);
171    __sync_sub_and_fetch(&val, 1);
172
173    return 0;
174}
175]====])
176
177CHECK_C_SOURCE_COMPILES("${SYNC_BUILTINS_TEST_SOURCE}" HAVE_ATOMIC_BUILTINS)
178IF(NOT HAVE_ATOMIC_BUILTINS)
179    MESSAGE(WARNING "Libucl references could be thread-unsafe because atomic builtins are missing")
180ENDIF(NOT HAVE_ATOMIC_BUILTINS)
181
182SET(CMAKE_C_WARN_FLAGS "")
183CHECK_C_COMPILER_FLAG(-W SUPPORT_W)
184CHECK_C_COMPILER_FLAG(-Wno-pointer-sign SUPPORT_WPOINTER_SIGN)
185CHECK_C_COMPILER_FLAG(-Wno-unused-parameter SUPPORT_WUNUSED_PARAMETER)
186IF(SUPPORT_W)
187    SET(CMAKE_C_WARN_FLAGS "${CMAKE_C_WARN_FLAGS} -W")
188ENDIF(SUPPORT_W)
189IF(SUPPORT_WPOINTER_SIGN)
190	SET(CMAKE_C_WARN_FLAGS "${CMAKE_C_WARN_FLAGS} -Wno-pointer-sign")
191ENDIF(SUPPORT_WPOINTER_SIGN)
192IF(SUPPORT_WUNUSED_PARAMETER)
193	SET(CMAKE_C_WARN_FLAGS "${CMAKE_C_WARN_FLAGS} -Wno-unused-parameter")
194ENDIF(SUPPORT_WUNUSED_PARAMETER)
195
196SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_WARN_FLAGS}" )
197
198IF(ENABLE_URL_SIGN MATCHES "ON")
199	IF(OPENSSL_FOUND)
200		SET(HAVE_OPENSSL 1)
201		INCLUDE_DIRECTORIES("${OPENSSL_INCLUDE_DIR}")
202	ENDIF(OPENSSL_FOUND)
203ENDIF(ENABLE_URL_SIGN MATCHES "ON")
204
205SET(UCL_COMPILE_DEFS)
206IF(HAVE_FETCH_H)
207    LIST(APPEND UCL_COMPILE_DEFS -DHAVE_FETCH_H=1)
208ENDIF(HAVE_FETCH_H)
209IF(CURL_FOUND)
210    LIST(APPEND UCL_COMPILE_DEFS -DCURL_FOUND=1)
211ENDIF(CURL_FOUND)
212IF(HAVE_OPENSSL)
213    LIST(APPEND UCL_COMPILE_DEFS -DHAVE_OPENSSL=1)
214ENDIF(HAVE_OPENSSL)
215IF(HAVE_ATOMIC_BUILTINS)
216    LIST(APPEND UCL_COMPILE_DEFS -DHAVE_ATOMIC_BUILTINS=1)
217ENDIF(HAVE_ATOMIC_BUILTINS)
218
219SET(UCLSRC src/ucl_util.c
220		src/ucl_parser.c
221		src/ucl_emitter.c
222		src/ucl_emitter_streamline.c
223		src/ucl_emitter_utils.c
224		src/ucl_hash.c
225		src/ucl_schema.c
226		src/ucl_msgpack.c
227		src/ucl_sexp.c)
228
229SET(UCLHDR include/ucl.h
230		include/ucl++.h)
231
232SET (LIB_TYPE STATIC)
233IF (BUILD_SHARED_LIBS)
234  SET (LIB_TYPE SHARED)
235ENDIF (BUILD_SHARED_LIBS)
236ADD_LIBRARY(ucl ${LIB_TYPE} ${UCLSRC})
237ADD_LIBRARY(ucl::ucl ALIAS ucl)
238SET_TARGET_PROPERTIES(ucl PROPERTIES VERSION ${LIBUCL_VERSION} SOVERSION ${LIBUCL_VERSION_MAJOR})
239TARGET_INCLUDE_DIRECTORIES(ucl
240	PUBLIC
241	  include
242	PRIVATE
243	  src
244	  uthash
245	  klib)
246TARGET_COMPILE_DEFINITIONS(ucl
247    PRIVATE
248    ${UCL_COMPILE_DEFS}
249)
250
251IF(ENABLE_LUA MATCHES "ON")
252	IF(ENABLE_LUAJIT MATCHES "ON")
253		FindLua(VERSION_MAJOR "5" VERSION_MINOR "1" ROOT "${LUA_ROOT}")
254		IF(NOT LUA_FOUND)
255			MESSAGE(FATAL_ERROR "Lua not found, lua support is required")
256		ELSE(NOT LUA_FOUND)
257			INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}")
258		ENDIF(NOT LUA_FOUND)
259	ELSE(ENABLE_LUAJIT MATCHES "ON")
260		FindLua(VERSION_MAJOR "5" VERSION_MINOR "2" ROOT "${LUA_ROOT}")
261		IF(NOT LUA_FOUND)
262			FindLua(VERSION_MAJOR "5" VERSION_MINOR "1" ROOT "${LUA_ROOT}")
263		ENDIF(NOT LUA_FOUND)
264		IF(NOT LUA_FOUND)
265			MESSAGE(FATAL_ERROR "Lua not found, lua support is required")
266		ELSE(NOT LUA_FOUND)
267			INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}")
268		ENDIF(NOT LUA_FOUND)
269	ENDIF(ENABLE_LUAJIT MATCHES "ON")
270	SET(UCL_LUA_SRC lua/lua_ucl.c)
271	ADD_LIBRARY(lua-ucl ${LIB_TYPE} ${UCL_LUA_SRC})
272	ADD_LIBRARY(ucl::lua ALIAS lua-ucl)
273	IF(ENABLE_LUAJIT MATCHES "ON")
274		TARGET_LINK_LIBRARIES(lua-ucl "${LUAJIT_LIBRARY}")
275	ELSE(ENABLE_LUAJIT MATCHES "ON")
276		TARGET_LINK_LIBRARIES(lua-ucl "${LUA_LIBRARY}")
277	ENDIF(ENABLE_LUAJIT MATCHES "ON")
278	TARGET_LINK_LIBRARIES(lua-ucl ucl)
279	TARGET_INCLUDE_DIRECTORIES(lua-ucl PUBLIC include PRIVATE src uthash)
280	SET_TARGET_PROPERTIES(lua-ucl PROPERTIES
281		VERSION ${LIBUCL_VERSION}
282		SOVERSION ${LIBUCL_VERSION_MAJOR}
283		PUBLIC_HEADER include/lua_ucl.h)
284	INSTALL(TARGETS lua-ucl DESTINATION ${CMAKE_INSTALL_LIBDIR}
285			PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
286ENDIF()
287
288IF(HAVE_FETCH_H)
289    TARGET_LINK_LIBRARIES(ucl fetch)
290ELSE(HAVE_FETCH_H)
291    IF(CURL_FOUND)
292        TARGET_LINK_LIBRARIES(ucl ${CURL_LIBRARIES})
293    ENDIF(CURL_FOUND)
294ENDIF(HAVE_FETCH_H)
295IF(ENABLE_URL_SIGN MATCHES "ON")
296	IF(OPENSSL_FOUND)
297		TARGET_LINK_LIBRARIES(ucl ${OPENSSL_LIBRARIES})
298	ENDIF(OPENSSL_FOUND)
299ENDIF(ENABLE_URL_SIGN MATCHES "ON")
300
301IF(UNIX)
302    TARGET_LINK_LIBRARIES(ucl -lm)
303ENDIF(UNIX)
304
305SET_TARGET_PROPERTIES(ucl PROPERTIES
306	PUBLIC_HEADER "${UCLHDR}")
307
308INSTALL(TARGETS ucl DESTINATION ${CMAKE_INSTALL_LIBDIR}
309		PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
310
311IF(ENABLE_UTILS MATCHES "ON")
312    ADD_SUBDIRECTORY(utils)
313ENDIF()
314
315