Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #103 from redjack/feature/static-template
Browse files Browse the repository at this point in the history
Use cmake helper macros
  • Loading branch information
Douglas Creager committed Jun 30, 2015
2 parents 1ccea38 + 67ebf2b commit 26729a4
Show file tree
Hide file tree
Showing 6 changed files with 421 additions and 111 deletions.
9 changes: 7 additions & 2 deletions CMakeLists.txt
Expand Up @@ -12,6 +12,11 @@ set(RELEASE_DATE 2015-03-12)
project(${PROJECT_NAME})
enable_testing()

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(ParseArguments)
find_package(Prereqs)
find_package(CTargets)

#-----------------------------------------------------------------------
# Retrieve the current version number

Expand Down Expand Up @@ -49,8 +54,6 @@ if(GIT_SHA1_RESULT)
"Cannot determine git commit: " ${GIT_SHA1_RESULT})
endif(GIT_SHA1_RESULT)

find_package(PkgConfig)

#-----------------------------------------------------------------------
# Check for building on Tilera
# If the Tilera environment is installed, then $TILERA_ROOT is defined
Expand Down Expand Up @@ -110,6 +113,8 @@ endif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Check for prerequisite libraries

find_package(Threads)
set(THREADS_LDFLAGS "${CMAKE_THREAD_LIBS_INIT}")
set(THREADS_STATIC_LDFLAGS "${CMAKE_THREAD_LIBS_INIT}")

#-----------------------------------------------------------------------
# Include our subdirectories
Expand Down
215 changes: 215 additions & 0 deletions cmake/FindCTargets.cmake
@@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2015, RedJack, LLC.
# All rights reserved.
#
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------


#-----------------------------------------------------------------------
# Configuration options that control all of the below

set(ENABLE_SHARED YES CACHE BOOL "Whether to build a shared library")
set(ENABLE_SHARED_EXECUTABLES YES CACHE BOOL
"Whether to link executables using shared libraries")
set(ENABLE_STATIC YES CACHE BOOL "Whether to build a static library")


#-----------------------------------------------------------------------
# Library, with options to build both shared and static versions

function(target_add_shared_libraries TARGET_NAME LIBRARIES LOCAL_LIBRARIES)
foreach(lib ${LIBRARIES})
string(REPLACE "-" "_" lib ${lib})
string(TOUPPER ${lib} upperlib)
target_link_libraries(
${TARGET_NAME}
${${upperlib}_LDFLAGS}
)
endforeach(lib)
foreach(lib ${LOCAL_LIBRARIES})
target_link_libraries(${TARGET_NAME} ${lib}-shared)
endforeach(lib)
endfunction(target_add_shared_libraries)

function(target_add_static_libraries TARGET_NAME LIBRARIES LOCAL_LIBRARIES)
foreach(lib ${LIBRARIES})
string(REPLACE "-" "_" lib ${lib})
string(TOUPPER ${lib} upperlib)
target_link_libraries(
${TARGET_NAME}
${${upperlib}_STATIC_LDFLAGS}
)
endforeach(lib)
foreach(lib ${LOCAL_LIBRARIES})
target_link_libraries(${TARGET_NAME} ${lib}-static)
endforeach(lib)
endfunction(target_add_static_libraries)

set_property(GLOBAL PROPERTY ALL_LOCAL_LIBRARIES "")

function(add_c_library __TARGET_NAME)
set(options)
set(one_args OUTPUT_NAME PKGCONFIG_NAME VERSION)
set(multi_args LIBRARIES LOCAL_LIBRARIES SOURCES)
cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

if (__VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-dev)?$")
set(__VERSION_CURRENT "${CMAKE_MATCH_1}")
set(__VERSION_REVISION "${CMAKE_MATCH_2}")
set(__VERSION_AGE "${CMAKE_MATCH_3}")
else (__VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-dev)?$")
message(FATAL_ERROR "Invalid library version number: ${__VERSION}")
endif (__VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-dev)?$")

math(EXPR __SOVERSION "${__VERSION_CURRENT} - ${__VERSION_AGE}")

get_property(ALL_LOCAL_LIBRARIES GLOBAL PROPERTY ALL_LOCAL_LIBRARIES)
list(APPEND ALL_LOCAL_LIBRARIES ${__TARGET_NAME})
set_property(GLOBAL PROPERTY ALL_LOCAL_LIBRARIES "${ALL_LOCAL_LIBRARIES}")

if (ENABLE_SHARED OR ENABLE_SHARED_EXECUTABLES)
add_library(${__TARGET_NAME}-shared SHARED ${__SOURCES})
set_target_properties(
${__TARGET_NAME}-shared PROPERTIES
OUTPUT_NAME ${__OUTPUT_NAME}
CLEAN_DIRECT_OUTPUT 1
VERSION ${__VERSION}
SOVERSION ${__SOVERSION}
)

if (CMAKE_VERSION VERSION_GREATER "2.8.11")
target_include_directories(
${__TARGET_NAME}-shared PUBLIC
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
else (CMAKE_VERSION VERSION_GREATER "2.8.11")
include_directories(
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
endif (CMAKE_VERSION VERSION_GREATER "2.8.11")

target_add_shared_libraries(
${__TARGET_NAME}-shared
"${__LIBRARIES}"
"${__LOCAL_LIBRARIES}"
)

# We have to install the shared library if the user asked us to, or if
# the user asked us to link our programs with the shared library.
install(TARGETS ${__TARGET_NAME}-shared
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif (ENABLE_SHARED OR ENABLE_SHARED_EXECUTABLES)

if (ENABLE_STATIC OR NOT ENABLE_SHARED_EXECUTABLES)
add_library(${__TARGET_NAME}-static STATIC ${__SOURCES})
set_target_properties(
${__TARGET_NAME}-static PROPERTIES
OUTPUT_NAME ${__OUTPUT_NAME}
CLEAN_DIRECT_OUTPUT 1
)

if (CMAKE_VERSION VERSION_GREATER "2.8.11")
target_include_directories(
${__TARGET_NAME}-static PUBLIC
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
else (CMAKE_VERSION VERSION_GREATER "2.8.11")
include_directories(
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
endif (CMAKE_VERSION VERSION_GREATER "2.8.11")

target_add_static_libraries(
${__TARGET_NAME}-static
"${__LIBRARIES}"
"${__LOCAL_LIBRARIES}"
)
endif (ENABLE_STATIC OR NOT ENABLE_SHARED_EXECUTABLES)

if (ENABLE_STATIC)
# We DON'T have to install the static library if the user asked us to
# link our programs statically.
install(TARGETS ${__TARGET_NAME}-static
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif (ENABLE_STATIC)

set(prefix ${CMAKE_INSTALL_PREFIX})
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/${__PKGCONFIG_NAME}.pc.in
${CMAKE_CURRENT_BINARY_DIR}/${__PKGCONFIG_NAME}.pc
@ONLY
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${__PKGCONFIG_NAME}.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endfunction(add_c_library)


#-----------------------------------------------------------------------
# Executable

function(add_c_executable __TARGET_NAME)
set(options SKIP_INSTALL)
set(one_args OUTPUT_NAME)
set(multi_args LIBRARIES LOCAL_LIBRARIES SOURCES)
cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

add_executable(${__TARGET_NAME} ${__SOURCES})

if (CMAKE_VERSION VERSION_GREATER "2.8.11")
target_include_directories(
${__TARGET_NAME} PUBLIC
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
else (CMAKE_VERSION VERSION_GREATER "2.8.11")
include_directories(
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
endif (CMAKE_VERSION VERSION_GREATER "2.8.11")

if (ENABLE_SHARED_EXECUTABLES)
target_add_shared_libraries(
${__TARGET_NAME}
"${__LIBRARIES}"
"${__LOCAL_LIBRARIES}"
)
else (ENABLE_SHARED_EXECUTABLES)
target_add_static_libraries(
${__TARGET_NAME}
"${__LIBRARIES}"
"${__LOCAL_LIBRARIES}"
)
endif (ENABLE_SHARED_EXECUTABLES)

if (NOT __SKIP_INSTALL)
install(TARGETS ${__TARGET_NAME} RUNTIME DESTINATION bin)
endif (NOT __SKIP_INSTALL)
endfunction(add_c_executable)


#-----------------------------------------------------------------------
# Test case

pkgconfig_prereq(check OPTIONAL)

function(add_c_test TEST_NAME)
get_property(ALL_LOCAL_LIBRARIES GLOBAL PROPERTY ALL_LOCAL_LIBRARIES)
add_c_executable(
${TEST_NAME}
SKIP_INSTALL
OUTPUT_NAME ${TEST_NAME}
SOURCES ${TEST_NAME}.c
LIBRARIES check
LOCAL_LIBRARIES ${ALL_LOCAL_LIBRARIES}
)
add_test(${TEST_NAME} ${TEST_NAME})
endfunction(add_c_test)
51 changes: 51 additions & 0 deletions cmake/FindParseArguments.cmake
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2015, RedJack, LLC.
# All rights reserved.
#
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------


# CMake 2.8.4 and higher gives us cmake_parse_arguments out of the box. For
# earlier versions (RHEL5!) we have to define it ourselves. (The definition
# comes from <http://www.cmake.org/Wiki/CMakeMacroParseArguments>.)

if (CMAKE_VERSION VERSION_LESS "2.8.4")

MACRO(CMAKE_PARSE_ARGUMENTS prefix arg_names option_names)
SET(DEFAULT_ARGS)
FOREACH(arg_name ${arg_names})
SET(${prefix}_${arg_name})
ENDFOREACH(arg_name)
FOREACH(option ${option_names})
SET(${prefix}_${option} FALSE)
ENDFOREACH(option)

SET(current_arg_name DEFAULT_ARGS)
SET(current_arg_list)
FOREACH(arg ${ARGN})
SET(larg_names ${arg_names})
LIST(FIND larg_names "${arg}" is_arg_name)
IF (is_arg_name GREATER -1)
SET(${prefix}_${current_arg_name} ${current_arg_list})
SET(current_arg_name ${arg})
SET(current_arg_list)
ELSE (is_arg_name GREATER -1)
SET(loption_names ${option_names})
LIST(FIND loption_names "${arg}" is_option)
IF (is_option GREATER -1)
SET(${prefix}_${arg} TRUE)
ELSE (is_option GREATER -1)
SET(current_arg_list ${current_arg_list} ${arg})
ENDIF (is_option GREATER -1)
ENDIF (is_arg_name GREATER -1)
ENDFOREACH(arg)
SET(${prefix}_${current_arg_name} ${current_arg_list})
ENDMACRO(CMAKE_PARSE_ARGUMENTS)

else (CMAKE_VERSION VERSION_LESS "2.8.4")

include(CMakeParseArguments)

endif (CMAKE_VERSION VERSION_LESS "2.8.4")
76 changes: 76 additions & 0 deletions cmake/FindPrereqs.cmake
@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2015, RedJack, LLC.
# All rights reserved.
#
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------


#-----------------------------------------------------------------------
# Configuration options that control all of the below

set(PKG_CONFIG_PATH CACHE STRING "pkg-config search path")
if (PKG_CONFIG_PATH)
set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
endif (PKG_CONFIG_PATH)


#-----------------------------------------------------------------------
# pkg-config prerequisites

find_package(PkgConfig)

function(pkgconfig_prereq DEP)
set(options OPTIONAL)
set(one_args)
set(multi_args)
cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

string(REGEX REPLACE "[<>=].*" "" SHORT_NAME "${DEP}")
string(REPLACE "-" "_" SHORT_NAME "${SHORT_NAME}")
string(TOUPPER ${SHORT_NAME} UPPER_SHORT_NAME)
string(TOLOWER ${SHORT_NAME} LOWER_SHORT_NAME)

set(USE_CUSTOM_${UPPER_SHORT_NAME} NO CACHE BOOL
"Whether you want to provide custom details for ${LOWER_SHORT_NAME}")

if (NOT USE_CUSTOM_${UPPER_SHORT_NAME})
set(PKG_CHECK_ARGS)
if (NOT __OPTIONAL)
list(APPEND PKG_CHECK_ARGS REQUIRED)
endif (NOT __OPTIONAL)
list(APPEND PKG_CHECK_ARGS ${DEP})

pkg_check_modules(${UPPER_SHORT_NAME} ${PKG_CHECK_ARGS})
endif (NOT USE_CUSTOM_${UPPER_SHORT_NAME})

include_directories(${${UPPER_SHORT_NAME}_INCLUDE_DIRS})
link_directories(${${UPPER_SHORT_NAME}_LIBRARY_DIRS})
endfunction(pkgconfig_prereq)


#-----------------------------------------------------------------------
# find_library prerequisites

function(library_prereq LIB_NAME)
set(options OPTIONAL)
set(one_args)
set(multi_args)
cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

string(REPLACE "-" "_" SHORT_NAME "${LIB_NAME}")
string(TOUPPER ${SHORT_NAME} UPPER_SHORT_NAME)
string(TOLOWER ${SHORT_NAME} LOWER_SHORT_NAME)

set(USE_CUSTOM_${UPPER_SHORT_NAME} NO CACHE BOOL
"Whether you want to provide custom details for ${LOWER_SHORT_NAME}")

if (USE_CUSTOM_${UPPER_SHORT_NAME})
include_directories(${${UPPER_SHORT_NAME}_INCLUDE_DIRS})
link_directories(${${UPPER_SHORT_NAME}_LIBRARY_DIRS})
else (USE_CUSTOM_${UPPER_SHORT_NAME})
find_library(${UPPER_SHORT_NAME}_LIBRARIES ${LIB_NAME})
endif (USE_CUSTOM_${UPPER_SHORT_NAME})

endfunction(library_prereq)

0 comments on commit 26729a4

Please sign in to comment.