cmake_minimum_required(VERSION 3.10) project (luv C ASM) set(LUV_VERSION_MAJOR 1) set(LUV_VERSION_MINOR 51) set(LUV_VERSION_PATCH 0) set(LUV_VERSION ${LUV_VERSION_MAJOR}.${LUV_VERSION_MINOR}.${LUV_VERSION_PATCH}) if(NOT ${CMAKE_VERSION} VERSION_LESS "3.5.0") # generate compilation database used by C code intelligence tools set(CMAKE_EXPORT_COMPILE_COMMANDS ON) endif() option(BUILD_MODULE "Build as module" ON) option(BUILD_STATIC_LIBS "Build static library" OFF) option(BUILD_SHARED_LIBS "Build shared library" OFF) option(WITH_SHARED_LIBUV "Link to a shared libuv library instead of static linking" OFF) if (MINGW) add_definitions(-D_WIN32_WINNT=0x0600) endif (MINGW) if (WIN32) # replace /MD to /MT to avoid link msvcr*.dll # this needs to be before add_subdirectory calls so that they inherit the modified flags set(CompilerFlags CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_RELEASE) foreach(CompilerFlag ${CompilerFlags}) string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") endforeach() endif () if (NOT WITH_LUA_ENGINE) set(WITH_LUA_ENGINE "LuaJIT" CACHE STRING "Link to LuaJIT or PUC Lua" FORCE) set_property(CACHE WITH_LUA_ENGINE PROPERTY STRINGS "Lua;LuaJIT") endif (NOT WITH_LUA_ENGINE) if (NOT LUA_BUILD_TYPE) set(LUA_BUILD_TYPE "Static" CACHE STRING "Build Lua/LuaJIT as static, dynamic library, or use system one" FORCE) set_property(CACHE LUA_BUILD_TYPE PROPERTY STRINGS "Static;Dynamic;System") endif (NOT LUA_BUILD_TYPE) if (WITH_LUA_ENGINE STREQUAL Lua) if (NOT WIN32) add_definitions(-DLUA_USE_DLOPEN) endif (NOT WIN32) set(USE_LUAJIT OFF) else () set(USE_LUAJIT ON) endif () set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") if (WITH_SHARED_LIBUV) find_package(Libuv REQUIRED) include_directories(${LIBUV_INCLUDE_DIR}) else (WITH_SHARED_LIBUV) include_directories(deps/libuv/include) add_subdirectory(deps/libuv EXCLUDE_FROM_ALL) if (BUILD_MODULE) add_definitions( -DBUILDING_UV_SHARED ) endif (BUILD_MODULE) set(LIBUV_LIBRARIES uv_a) set_target_properties(uv_a PROPERTIES COMPILE_FLAGS "-fPIC") endif (WITH_SHARED_LIBUV) if (LUA) MESSAGE(STATUS "Lua: using information from luarocks") MESSAGE(STATUS "LUA_LIBDIR: " ${LUA_LIBDIR}) MESSAGE(STATUS "LUA_LIBFILE: " ${LUA_LIBFILE}) MESSAGE(STATUS "LUA_INCDIR: " ${LUA_INCDIR}) MESSAGE(STATUS "LUA: " ${LUA}) SET(LUA_EXECUTABLE "${LUA}") SET(LUA_INCLUDE_DIR "${LUA_INCDIR}") SET(LUA_PACKAGE_PATH "${LUADIR}") SET(LUA_PACKAGE_CPATH "${LIBDIR}") SET(INSTALL_LIB_DIR ${LIBDIR}) if (LUA_LIBDIR) if (NOT LUA_LIBFILE) # If LIBDIR is set but LIBFILE is not, then that means # Luarocks 2.x is being used, and we'll need to find the lib # ourselves GET_FILENAME_COMPONENT(LUA_EXEC_NAME ${LUA_EXECUTABLE} NAME_WE) IF(LUA_EXEC_NAME STREQUAL "luajit") FIND_LIBRARY(LUA_LIBRARIES NAMES luajit libluajit PATHS ${LUA_LIBDIR} NO_DEFAULT_PATH) ELSEIF(LUA_EXEC_NAME MATCHES "lua.*") FIND_LIBRARY(LUA_LIBRARIES NAMES lua lua54 lua53 lua52 lua51 liblua liblua54 liblua53 liblua52 liblua51 PATHS ${LUA_LIBDIR} NO_DEFAULT_PATH) ENDIF() else() # Otherwise, we can just use the LIBFILE that Luarocks provides get_filename_component(LUA_LIBRARIES "${LUA_LIBDIR}/${LUA_LIBFILE}" ABSOLUTE) endif() MESSAGE(STATUS "Lua library: ${LUA_LIBRARIES}") else() MESSAGE(STATUS "Lua library not set, presuming LuaRocks config has link_lua_explicitly set to false") endif() include_directories(${LUA_INCLUDE_DIR}) else (LUA) if (LUA_BUILD_TYPE STREQUAL System) if (USE_LUAJIT) # We only link the libs on Windows, so find_package fully succeeding # is only required on Windows if (WIN32 OR CYGWIN) find_package(LuaJIT REQUIRED) link_directories(${LUAJIT_LIBRARIES}) else() find_package(LuaJIT) endif() if(NOT LUAJIT_INCLUDE_DIR) message( FATAL_ERROR "Failed to find LuaJIT headers. Variable `LUAJIT_INCLUDE_DIR' expected to be defined.") endif() include_directories(${LUAJIT_INCLUDE_DIR}) else (USE_LUAJIT) # We only link the libs on Windows, so find_package fully succeeding # is only required on Windows if (WIN32 OR CYGWIN) find_package(Lua REQUIRED) else() find_package(Lua) endif() if(NOT LUA_INCLUDE_DIR) message( FATAL_ERROR "Failed to find Lua headers. Variable `LUA_INCLUDE_DIR' expected to be defined.") endif() include_directories(${LUA_INCLUDE_DIR}) endif (USE_LUAJIT) else (LUA_BUILD_TYPE STREQUAL System) if (LUA_BUILD_TYPE STREQUAL Static) SET(WITH_SHARED_LUA OFF) else (LUA_BUILD_TYPE STREQUAL Static) SET(WITH_SHARED_LUA ON) endif (LUA_BUILD_TYPE STREQUAL Static) if (USE_LUAJIT) include(deps/luajit.cmake) set(LUA_INCLUDE_DIR deps/luajit/src) set(LUAJIT_LIBRARIES luajit-5.1) else(USE_LUAJIT) include(deps/lua.cmake) set(LUA_INCLUDE_DIR deps/lua) set(LUA_LIBRARIES lualib) endif (USE_LUAJIT) include_directories(${LUA_INCLUDE_DIR}) set(LUA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${LUA_INCLUDE_DIR}) endif (LUA_BUILD_TYPE STREQUAL System) endif (LUA) if (EXISTS "${LUA_INCLUDE_DIR}/lua.h") # At least 5.[012] have different ways to express the version # so all of them need to be tested. Lua 5.2 defines LUA_VERSION # and LUA_RELEASE as joined by the C preprocessor, so avoid those. # lua 5.2 and above file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" LUA_VERSION_MAJOR REGEX "^#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"Lua [0-9]+") file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" LUA_VERSION_MINOR REGEX "^#define[ \t]+LUA_VERSION_MINOR[ \t]+\"Lua [0-9]+") if(NOT LUA_VERSION_MAJOR AND NOT LUA_VERSION_MINOR) file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_strings REGEX "^#define[ \t]+LUA_VERSION([ \t]+\"Lua [0-9]|_[MR]).*") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};") if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};") set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}") else () string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$") string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") endif () string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}") string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}") string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}") endif () unset(lua_version_strings) endif() endif() if (BUILD_MODULE) add_library(luv MODULE src/luv.c) set_target_properties(luv PROPERTIES PREFIX "") list(APPEND ACTIVE_TARGETS "luv") endif (BUILD_MODULE) if (BUILD_STATIC_LIBS) add_library(libluv_a STATIC src/luv.c) set_target_properties(libluv_a PROPERTIES OUTPUT_NAME luv) list(APPEND ACTIVE_TARGETS "libluv_a") endif (BUILD_STATIC_LIBS) if (BUILD_SHARED_LIBS) add_library(libluv SHARED src/luv.c) set_target_properties(libluv PROPERTIES VERSION ${LUV_VERSION} SOVERSION ${LUV_VERSION_MAJOR} OUTPUT_NAME luv) if(APPLE) set_target_properties(libluv PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") endif(APPLE) list(APPEND ACTIVE_TARGETS "libluv") endif (BUILD_SHARED_LIBS) if(APPLE) set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress" ) # execute_process(COMMAND which luajit OUTPUT_VARIABLE LUAJIT) # set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS # "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -bundle_loader ${LUAJIT}" # ) endif() if(NOT LUA_COMPAT53_DIR) set(LUA_COMPAT53_DIR deps/lua-compat-5.3) endif() if(DEFINED ENV{LUA_COMPAT53_DIR}) set(LUA_COMPAT53_DIR $ENV{LUA_COMPAT53_DIR}) endif() include_directories(${LUA_COMPAT53_DIR}/c-api) if(WIN32) add_definitions(-DLUA_BUILD_AS_DLL -DLUA_LIB) endif() add_executable(test EXCLUDE_FROM_ALL src/test.c src/luv.c) # Need to link Lua/LuaJIT libraries on non-Windows for the test executable if ((LUAJIT_LIBRARIES OR LUA_LIBRARIES) AND NOT (WIN32 OR CYGWIN)) if(USE_LUAJIT) target_link_libraries(test ${LUAJIT_LIBRARIES}) else() target_link_libraries(test ${LUA_LIBRARIES}) endif() endif() list(APPEND ACTIVE_TARGETS "test") foreach(TARGET_NAME ${ACTIVE_TARGETS}) if(WIN32 OR CYGWIN) if (LUA) target_link_libraries(${TARGET_NAME} ${LIBUV_LIBRARIES} ${LUA_LIBRARIES}) else (LUA) if (USE_LUAJIT) target_link_libraries(${TARGET_NAME} ${LIBUV_LIBRARIES} ${LUAJIT_LIBRARIES}) else (USE_LUAJIT) if (LUA_BUILD_TYPE STREQUAL System) target_link_libraries(${TARGET_NAME} ${LIBUV_LIBRARIES} ${LUA_LIBRARIES}) else (LUA_BUILD_TYPE STREQUAL System) target_link_libraries(${TARGET_NAME} ${LIBUV_LIBRARIES} lualib) endif (LUA_BUILD_TYPE STREQUAL System) endif (USE_LUAJIT) endif (LUA) elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") target_link_libraries(${TARGET_NAME} ${LIBUV_LIBRARIES} rt) else() target_link_libraries(${TARGET_NAME} ${LIBUV_LIBRARIES}) endif() endforeach() if (NOT LUA) if (BUILD_MODULE) if (WIN32) set(MODULE_INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") else (WIN32) set(MODULE_INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib/lua/${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}") endif (WIN32) endif (BUILD_MODULE) if (BUILD_STATIC_LIBS) set(STATICLIBS_INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for static libraries") endif (BUILD_STATIC_LIBS) if (BUILD_SHARED_LIBS) set(SHAREDLIBS_INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for runtime components") set(SHAREDLIBS_INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for shared libraries") endif (BUILD_SHARED_LIBS) else () # use paths from luaRocks set(MODULE_INSTALL_LIB_DIR "${INSTALL_LIB_DIR}") set(STATICLIBS_INSTALL_LIB_DIR "${INSTALL_LIB_DIR}") set(SHAREDLIBS_INSTALL_LIB_DIR "${INSTALL_LIB_DIR}") endif () # header install paths are LuaRocks-agnostic, so just use CMAKE_INSTALL_PREFIX regardless if (BUILD_STATIC_LIBS) set(STATICLIBS_INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include/luv" CACHE PATH "Installation directory for headers") endif (BUILD_STATIC_LIBS) if (BUILD_SHARED_LIBS) set(SHAREDLIBS_INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include/luv" CACHE PATH "Installation directory for headers") endif (BUILD_SHARED_LIBS) if (CMAKE_INSTALL_PREFIX) if (BUILD_MODULE) install(TARGETS luv ARCHIVE DESTINATION "${MODULE_INSTALL_LIB_DIR}" LIBRARY DESTINATION "${MODULE_INSTALL_LIB_DIR}" ) endif (BUILD_MODULE) if (BUILD_STATIC_LIBS) install(TARGETS libluv_a ARCHIVE DESTINATION "${STATICLIBS_INSTALL_LIB_DIR}" LIBRARY DESTINATION "${STATICLIBS_INSTALL_LIB_DIR}" ) install( FILES src/luv.h src/util.h src/lhandle.h src/lreq.h DESTINATION "${STATICLIBS_INSTALL_INC_DIR}" ) endif (BUILD_STATIC_LIBS) if (BUILD_SHARED_LIBS) install(TARGETS libluv RUNTIME DESTINATION "${SHAREDLIBS_INSTALL_BIN_DIR}" ARCHIVE DESTINATION "${SHAREDLIBS_INSTALL_LIB_DIR}" LIBRARY DESTINATION "${SHAREDLIBS_INSTALL_LIB_DIR}" ) if(UNIX OR MINGW) set(prefix ${CMAKE_INSTALL_PREFIX}) set(includedir ${SHAREDLIBS_INSTALL_INC_DIR}) set(libdir ${SHAREDLIBS_INSTALL_LIB_DIR}) configure_file(libluv.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libluv.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libluv.pc DESTINATION ${SHAREDLIBS_INSTALL_LIB_DIR}/pkgconfig) endif() install( FILES src/luv.h src/util.h src/lhandle.h src/lreq.h DESTINATION "${SHAREDLIBS_INSTALL_INC_DIR}" ) endif (BUILD_SHARED_LIBS) endif (CMAKE_INSTALL_PREFIX)