Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various cmake improvements #10

Open
wants to merge 18 commits into
base: omemo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ build/
*.a

# IDE-related files
CMakeLists.txt.user*

# OS generated files
.DS_Store*
Expand Down
97 changes: 57 additions & 40 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,64 +1,68 @@
cmake_minimum_required(VERSION 2.8.4)
cmake_minimum_required(VERSION 3.5)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules/")
project(omemo-c)

if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()

SET(OMEMO_C_VERSION_MAJOR 0)
SET(OMEMO_C_VERSION_MINOR 5)
SET(OMEMO_C_VERSION_PATCH 0)
SET(OMEMO_C_VERSION ${OMEMO_C_VERSION_MAJOR}.${OMEMO_C_VERSION_MINOR}.${OMEMO_C_VERSION_PATCH})
set(OMEMO_C_VERSION_MAJOR 0)
set(OMEMO_C_VERSION_MINOR 5)
set(OMEMO_C_VERSION_PATCH 0)
set(OMEMO_C_VERSION ${OMEMO_C_VERSION_MAJOR}.${OMEMO_C_VERSION_MINOR}.${OMEMO_C_VERSION_PATCH})

SET(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
SET(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE STRING "The directory the binaries are installed in")
SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "The directory the libraries are installed in")
SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in")
SET(INSTALL_PKGCONFIG_DIR "${LIB_INSTALL_DIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
include(GNUInstallDirs)

INCLUDE(CheckSymbolExists)
INCLUDE(CheckCCompilerFlag)
INCLUDE(TestBigEndian)
option(GENERATE_PKGCONFIG "Generate and install pkg-config files" ${UNIX})
set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
set(BUILD_WITH_PROTOBUF "auto" CACHE STRING "How to find/link with protobuf")
set_property(CACHE BUILD_WITH_PROTOBUF PROPERTY STRINGS auto static bundled)
# auto - try to find any system protobuf-c library
# static - try to find static system protobuf-c library
# bundled - download and build protobuf-c from github

include(CheckSymbolExists)
include(CheckCCompilerFlag)
include(TestBigEndian)

CHECK_SYMBOL_EXISTS(memset_s "string.h" HAVE_MEMSET_S)

IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
CHECK_SYMBOL_EXISTS(SecureZeroMemory "Windows.h;WinBase.h" HAVE_SECUREZEROMEMORY)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
endif(CMAKE_SYSTEM_NAME MATCHES "Windows")

IF(BUILD_TESTING)
if(BUILD_TESTING)
enable_testing()
ENDIF(BUILD_TESTING)
endif(BUILD_TESTING)

IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0 -Wall -Wmissing-field-initializers -Wno-missing-braces -Wparentheses")
ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0 -Wall -Wmissing-field-initializers -Wno-missing-braces -Wparentheses")
endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")

IF(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_COMPILER_IS_GNUCC)
CHECK_C_COMPILER_FLAG("-Wsign-conversion" GCC_WARN_SIGN_CONVERSION)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare")
IF(GCC_WARN_SIGN_CONVERSION)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-conversion")
ENDIF(GCC_WARN_SIGN_CONVERSION)
ENDIF(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare")
if(GCC_WARN_SIGN_CONVERSION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-conversion")
endif(GCC_WARN_SIGN_CONVERSION)
endif(CMAKE_COMPILER_IS_GNUCC)

IF(CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch -Wunused-variable -Wunused-value -Wshadow -Wint-conversion -Wpointer-sign -Wprotocol -Wshorten-64-to-32")
ENDIF(CMAKE_C_COMPILER_ID MATCHES "Clang")
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch -Wunused-variable -Wunused-value -Wshadow -Wint-conversion -Wpointer-sign -Wprotocol -Wshorten-64-to-32")
endif(CMAKE_C_COMPILER_ID MATCHES "Clang")

IF(HAVE_MEMSET_S)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_MEMSET_S=1")
ENDIF(HAVE_MEMSET_S)
if(HAVE_MEMSET_S)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_MEMSET_S=1")
endif(HAVE_MEMSET_S)

TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
IF(WORDS_BIGENDIAN)
if(WORDS_BIGENDIAN)
ADD_DEFINITIONS(-DWORDS_BIGENDIAN)
ENDIF(WORDS_BIGENDIAN)
endif(WORDS_BIGENDIAN)

IF(COVERAGE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
SET(LINK_FLAGS "${LINK_FLAGS} -fprofile-arcs -ftest-coverage")
if(COVERAGE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(LINK_FLAGS "${LINK_FLAGS} -fprofile-arcs -ftest-coverage")

add_custom_command(OUTPUT run_coverage
COMMAND ctest
Expand All @@ -68,10 +72,23 @@ IF(COVERAGE)
COMMENT Collecting and creating coverage information
)
add_custom_target( coverage DEPENDS run_coverage )
ENDIF(COVERAGE)
endif(COVERAGE)

add_subdirectory(src)

IF(BUILD_TESTING)
if(BUILD_TESTING)
add_subdirectory(tests)
ENDIF(BUILD_TESTING)
endif(BUILD_TESTING)

# this hack makes files visible in the project view of QtCreator
add_custom_target(useful_files ALL
SOURCES
src/lib${PROJECT_NAME}.pc.in
src/${PROJECT_NAME}-config.cmake.in
CMakeModules/BlackBerry.toolchain.cmake
CMakeModules/FindCheck.cmake
CMakeModules/FindProtobuf_C.cmake
CMakeModules/iOS.toolchain.cmake
CMakeModules/protobuf_c_bundled.cmake
)

105 changes: 105 additions & 0 deletions CMakeModules/FindProtobuf_C.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#=============================================================================
# Copyright 2024 Psi+ Project, Vitaly Tonkacheyev
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================

if( Protobuf_C_INCLUDE_DIR AND Protobuf_C_LIBRARY )
# in cache already
set(Protobuf_C_FIND_QUIETLY TRUE)
endif()

if( UNIX AND NOT( APPLE OR CYGWIN ) )
find_package( PkgConfig QUIET )
pkg_check_modules( PROTOBUF_C QUIET protobuf-c )
if( PC_PROTOBUF_C_FOUND )
set( PROTOBUF_C_DEFINITIONS ${PC_PROTOBUF_C_CFLAGS} ${PC_PROTOBUF_C_CFLAGS_OTHER} )
add_library(Protobuf_C::Protobuf_C ALIAS PkgConfig::PROTOBUF_C)
endif()
endif()

if (NOT(PC_Protobuf_C_FOUND))
set( Protobuf_C_ROOT "" CACHE STRING "Path to protobuf-c library" )

unset(Protobuf_C_INCLUDE_DIR CACHE)
find_path(
Protobuf_C_INCLUDE_DIR protobuf-c.h
HINTS
${Protobuf_C_ROOT}/include
${PC_PROTOBUF_C_INCLUDEDIR}
${PC_PROTOBUF_C_INCLUDE_DIRS}
PATH_SUFFIXES
""
protobuf-c
)

set(PROTOBUF_LIB_DIRS
${PC_PROTOBUF_C_LIBDIR}
${PC_PROTOBUF_C_LIBRARY_DIRS}
${Protobuf_C_ROOT}/lib)
if(BUILD_WITH_PROTOBUF STREQUAL static)
message(STATUS "Looking for static Protobuf-C")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(Protobuf_C_NAMES
protobuf-c.lib
libprotobuf-c.a
)
else()
message(STATUS "Looking for any Protobuf-C")
set(Protobuf_C_NAMES
protobuf-c
libprotobuf-c
)
list(APPEND PROTOBUF_LIB_DIRS ${Protobuf_C_ROOT}/bin)
endif()
unset(Protobuf_C_LIBRARY CACHE)
find_library(
Protobuf_C_LIBRARY protobuf-c
NAMES ${Protobuf_C_NAMES}
HINTS
${PROTOBUF_LIB_DIRS}
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Protobuf_C
DEFAULT_MSG
Protobuf_C_LIBRARY
Protobuf_C_INCLUDE_DIR
)
message(STATUS "Found ${Protobuf_C_LIBRARY}")

if( Protobuf_C_FOUND )
set( Protobuf_C_LIBRARIES ${Protobuf_C_LIBRARY} )
set( Protobuf_INCLUDE_DIRS ${Protobuf_C_INCLUDE_DIR} )
add_library(protobuf-c IMPORTED UNKNOWN)
set_property(TARGET protobuf-c PROPERTY
IMPORTED_LOCATION "${Protobuf_C_LIBRARY}")
add_library(Protobuf_C::Protobuf_C ALIAS protobuf-c)
target_include_directories(protobuf-c INTERFACE "${Protobuf_C_INCLUDE_DIR}")
endif()

mark_as_advanced( Protobuf_C_INCLUDE_DIR Protobuf_C_LIBRARY )
endif()
72 changes: 72 additions & 0 deletions CMakeModules/protobuf_c_bundled.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
cmake_minimum_required(VERSION 3.10.0)

set(ProtobufCGitRepo "https://github.com/protobuf-c/protobuf-c.git")

message(STATUS "Protobuf_C: using bundled")

set(PROTOBUF_C_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/protobuf-c)
set(PROTOBUF_C_BUILD_DIR ${PROTOBUF_C_PREFIX}/build)
set(PROTOBUF_C_INSTALL_DIR ${PROTOBUF_C_PREFIX}/install)
set(Protobuf_C_INCLUDE_DIR ${PROTOBUF_C_INSTALL_DIR}/include)
set(PROTOBUF_C_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-c/src/ProtobufCProject/build-cmake)
set(Protobuf_C_LIBRARY_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}protobuf-c${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(Protobuf_C_LIBRARY ${PROTOBUF_C_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${Protobuf_C_LIBRARY_NAME})
if(APPLE)
set(COREFOUNDATION_LIBRARY "-framework CoreFoundation")
set(COREFOUNDATION_LIBRARY_SECURITY "-framework Security")
list(APPEND PROTOBUF_C_LIBRARY ${COREFOUNDATION_LIBRARY} ${COREFOUNDATION_LIBRARY_SECURITY})
endif()

include(ExternalProject)
#set CMake options and transfer the environment to an external project

option(HIDE_LINUX_PATH "Hide protobuf linux path for croscompiling" OFF)

if(WIN32)
set(HIDE_FLAGS
-DCMAKE_IGNORE_PATH="/usr/include/protobuf-c"
-DCMAKE_SYSTEM_IGNORE_PATH="/usr/include/protobuf-c"
)
endif()

set(PROTOBUF_C_BUILD_OPTIONS
${HIDE_FLAGS}
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_FIND_DEBUG_MODE=ON
-DBUILD_SHARED_LIBS=OFF
-DBUILD_PROTOC=OFF
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX=${PROTOBUF_C_INSTALL_DIR}
-DCMAKE_PREFIX_PATH=C:/Users/User/Documents/cmake-prefix;${CMAKE_PREFIX_PATH}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
-DOSX_FRAMEWORK=OFF
-DBUILD_TESTS=OFF
)

include(FindGit)
find_package(Git REQUIRED)
ExternalProject_Add(ProtobufCProject
PREFIX ${PROTOBUF_C_PREFIX}
BINARY_DIR ${PROTOBUF_C_BUILD_DIR}
GIT_REPOSITORY "${ProtobufCGitRepo}"
CONFIGURE_COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ${PROTOBUF_C_BUILD_OPTIONS} ${PROTOBUF_C_SOURCE_DIR}
CMAKE_ARGS ${PROTOBUF_C_BUILD_OPTIONS}
BUILD_BYPRODUCTS ${Protobuf_C_LIBRARY}
UPDATE_COMMAND ""
)
add_library(bundled-protobuf-c IMPORTED STATIC)
set_property(TARGET bundled-protobuf-c PROPERTY IMPORTED_LOCATION "${Protobuf_C_LIBRARY}")
set_property(TARGET bundled-protobuf-c PROPERTY INTERFACE_LINK_LIBRARIES "${Protobuf_C_LIBRARY}")
target_include_directories(bundled-protobuf-c INTERFACE "${Protobuf_C_INCLUDE_DIR}")
add_library(Protobuf_C::Protobuf_C ALIAS bundled-protobuf-c)

message(STATUS "LIB=${Protobuf_C_LIBRARY}")
message(STATUS "HEADER=${Protobuf_C_INCLUDE_DIR}")

# bundling static libraries is quite tricky and error prone
# see https://stackoverflow.com/questions/37924383/combining-several-static-libraries-into-one-using-cmake
# and other similar topics. So instead we are going to install the bundled lib
install(FILES ${Protobuf_C_LIBRARY} DESTINATION ${CMAKE_INSTALL_LIBDIR})
Loading