Skip to content

Commit e5226f5

Browse files
committed
Adds support for modern CMake
The primary purpose of this commit is to incorporate modern CMake (>= 3.1) best practices. As a result, a reorganization of the directory structure as well as a few minor code cleanups was required. A summary of those changes follows: * Moves all header files into a separate include directory. * The test directory was renamed to apps, to allow for future unit tests to be written and included in a directory named test. * Makes the GKlib apps disabled by default if the GKlib library is not the top CMake project and enabled if it is. This way, when GKlib is a dependency of another project, the apps are not build by default. An option, GKLIB_BUILD_APPS, was added to allow projects depending on GKlib to also build the apps. * The win32 shims should only be included when compiling in a Windows environment. Upstream checks this by testing the CMake variable `MSVC`. However, this commit uses generator expressions and the more general test of the CMake Platform ID being equal to `Windows`. * All options and other configurable behavior of the CMakeLists file is implemented using generator-expressions. * Replaces the following project defined macros: * __OPENMP__ -> _OPENMP * WIN32 -> _WIN32 with predefined macros for conforming systems. * Adds the file GKlibSystem.cmake which includes lots of nice default settings for different things. Along with this, the CMake variable GKLIB_SYSTEM is added. This variable, when defined, will point to a CMake script, like GKlibSystem.cmake, where compiler options and the like can be specified. This allows the user of the build system to have a file where they manage common CMake settings without affecting the core CMake logic and thus imposing those settings on other users of this build. * Adds support for testing successful compilation (w/ and w/o apps) on Travis using Linux, Windows, and Apple * Incorporates changes from pkg-petsc
1 parent c79ea22 commit e5226f5

68 files changed

Lines changed: 425 additions & 297 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# root key configurations (defaults).
2+
dist: xenial
3+
4+
# operating systems configurations.
5+
os:
6+
- linux
7+
- osx
8+
- windows
9+
10+
# language configurations.
11+
language: c
12+
13+
# env variable to toggle apps on and off.
14+
env:
15+
- CMAKE_OPTS=-DGKLIB_BUILD_APPS=ON
16+
- CMAKE_OPTS=-DGKLIB_BUILD_APPS=OFF
17+
18+
# invalid configurations to be explicitly included.
19+
jobs:
20+
include:
21+
- os: linux
22+
compiler: clang
23+
env: CMAKE_OPTS=-DGKLIB_BUILD_APPS=ON
24+
- os: linux
25+
compiler: clang
26+
env: CMAKE_OPTS=-DGKLIB_BUILD_APPS=OFF
27+
28+
# Override default script.
29+
script:
30+
- cmake ${CMAKE_OPTS} . && cmake --build . && ctest --output-on-failure

CMakeLists.txt

Lines changed: 205 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,212 @@
1-
cmake_minimum_required(VERSION 2.8)
2-
project(GKlib C)
1+
cmake_minimum_required(VERSION 3.1)
32

4-
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)
3+
# ...
4+
project(GKlib
5+
VERSION 0.0.1
6+
LANGUAGES C)
57

6-
get_filename_component(abs "." ABSOLUTE)
7-
set(GKLIB_PATH ${abs})
8-
unset(abs)
9-
include(GKlibSystem.cmake)
8+
# include required CMake modules
9+
include(CheckCCompilerFlag)
10+
include(CheckCSourceCompiles)
11+
include(CheckFunctionExists)
12+
include(CheckIncludeFile)
13+
include(CMakePackageConfigHelpers)
14+
include(GNUInstallDirs)
1015

11-
include_directories(".")
12-
if(MSVC)
13-
include_directories("win32")
14-
file(GLOB win32_sources RELATIVE "win32" "*.c")
15-
else(MSVC)
16-
set(win32_sources, "")
17-
endif(MSVC)
16+
#-------------------------------------------------------------------------------
17+
# DEFAULT CONFIGURATIONS
18+
#-------------------------------------------------------------------------------
19+
if (DEFINED GKLIB_SYSTEM)
20+
include(${GKLIB_SYSTEM})
21+
endif()
1822

19-
add_library(GKlib ${GKlib_sources} ${win32_sources})
23+
#-------------------------------------------------------------------------------
24+
# OPTIONS
25+
#-------------------------------------------------------------------------------
26+
option(ASSERT "turn asserts on" OFF)
27+
option(ASSERT2 "additional assertions" OFF)
28+
option(DEBUG "add debugging support" OFF)
29+
option(GPROF "add gprof support" OFF)
30+
option(GKRAND "enable GKRAND support" OFF)
31+
option(GKREGEX "enable GKREGEX support" OFF)
32+
option(OPENMP "enable OpenMP support" OFF)
33+
option(PCRE "enable PCRE support" OFF)
2034

21-
if(UNIX)
22-
target_link_libraries(GKlib m)
23-
endif(UNIX)
35+
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
36+
option(GKLIB_BUILD_APPS "build the GKlib applications" ON)
37+
else()
38+
option(GKLIB_BUILD_APPS "build the GKlib applications" OFF)
39+
endif()
2440

25-
include_directories("test")
26-
add_subdirectory("test")
41+
#-------------------------------------------------------------------------------
42+
# LIBRARY configuration
43+
#-------------------------------------------------------------------------------
44+
add_library(${PROJECT_NAME})
2745

28-
install(TARGETS GKlib
29-
ARCHIVE DESTINATION lib/${LINSTALL_PATH}
30-
LIBRARY DESTINATION lib/${LINSTALL_PATH})
31-
install(FILES ${GKlib_includes} DESTINATION include/${HINSTALL_PATH})
46+
target_sources(${PROJECT_NAME}
47+
PRIVATE src/b64.c src/blas.c src/cache.c src/csr.c src/error.c src/evaluate.c
48+
src/fkvkselect.c src/fs.c src/getopt.c src/gk_util.c src/gkregex.c
49+
src/graph.c src/htable.c src/io.c src/itemsets.c src/mcore.c
50+
src/memory.c src/pqueue.c src/random.c src/rw.c src/seq.c src/sort.c
51+
src/string.c src/timers.c src/tokenizer.c
52+
# these are only included below so that they appear when using IDEs
53+
include/GKlib/GKlib.h include/GKlib/gk_arch.h include/GKlib/gk_defs.h
54+
include/GKlib/gk_externs.h include/GKlib/gk_getopt.h
55+
include/GKlib/gk_macros.h include/GKlib/gk_mkblas.h
56+
include/GKlib/gk_mkmemory.h include/GKlib/gk_mkpqueue.h
57+
include/GKlib/gk_mkpqueue2.h include/GKlib/gk_mkrandom.h
58+
include/GKlib/gk_mksort.h include/GKlib/gk_mkutils.h
59+
include/GKlib/gk_proto.h include/GKlib/gk_struct.h
60+
include/GKlib/gk_types.h include/GKlib/gkregex.h
61+
include/GKlib/gk_ms_inttypes.h include/GKlib/gk_ms_stat.h
62+
include/GKlib/gk_ms_stdint.h
63+
# the following are shims for win32 systems
64+
$<$<PLATFORM_ID:Windows>:src/win32/adapt.c
65+
include/GKlib/win32/adapt.h>)
66+
67+
target_compile_definitions(${PROJECT_NAME}
68+
PUBLIC $<$<PLATFORM_ID:Linux>:LINUX>)
69+
70+
target_include_directories(${PROJECT_NAME}
71+
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/GKlib>
72+
$<INSTALL_INTERFACE:include/GKlib>)
73+
74+
target_link_libraries(${PROJECT_NAME}
75+
PUBLIC $<$<NOT:$<C_COMPILER_ID:MSVC>>:m>)
76+
77+
set_target_properties(${PROJECT_NAME} PROPERTIES
78+
SOVERSION ${PROJECT_VERSION_MAJOR}
79+
VERSION ${PROJECT_VERSION})
80+
81+
add_library(GKlib::GKlib ALIAS ${PROJECT_NAME})
82+
83+
#-------------------------------------------------------------------------------
84+
# OPTIONS configuration
85+
#-------------------------------------------------------------------------------
86+
target_compile_definitions(${PROJECT_NAME}
87+
PUBLIC $<$<NOT:$<BOOL:${ASSERT}>>:NDEBUG>
88+
$<$<NOT:$<BOOL:${ASSERT2}>>:NDEBUG2>
89+
$<$<BOOL:${DEBUG}>:DEBUG>
90+
$<$<BOOL:${GKRAND}>:GKRAND>)
91+
92+
#-------------------------------------------------------------------------------
93+
# FEATURE AVAILABILITY checks
94+
#-------------------------------------------------------------------------------
95+
check_include_file(execinfo.h HAVE_EXECINFO_H)
96+
check_function_exists(getline HAVE_GETLINE)
97+
98+
# regular expressions
99+
if(PCRE)
100+
check_include_file(pcreposix.h HAVE_PCREPOSIX_H)
101+
if(NOT HAVE_PCREPOSIX_H)
102+
message(WARNING "PCRE was requested, but is not available")
103+
endif()
104+
endif()
105+
if(NOT HAVE_PCREPOSIX_H)
106+
check_include_file(regex.h HAVE_REGEX_H)
107+
if(NOT HAVE_REGEX_H)
108+
set(USE_GKREGEX ON)
109+
endif()
110+
endif()
111+
112+
# profiling support
113+
if(GPROF)
114+
check_c_compiler_flag("-pg" HAVE_GPROF_SUPPORT)
115+
if(NOT HAVE_GPROF_SUPPORT)
116+
message(WARNING "GPROF support was requested, but is not available")
117+
endif()
118+
endif()
119+
120+
# openmp support
121+
if(OPENMP)
122+
find_package(OpenMP)
123+
if(NOT OpenMP_C_FOUND)
124+
message(WARNING "OpenMP was requested, but is not available")
125+
endif()
126+
endif()
127+
128+
# thread local storage
129+
if(NOT DEFINED HAVE_TLS)
130+
set(TLS_NAME "" CACHE INTERNAL "Thread local keyword")
131+
foreach(tls_name "__thread" "__declspec(thread)")
132+
unset(HAVE_TLS CACHE)
133+
check_c_source_compiles("${tls_name} int x; int main(void) { return 0; }"
134+
HAVE_TLS)
135+
if (HAVE_TLS)
136+
set(TLS_NAME ${tls_name} CACHE INTERNAL "Thread local keyword")
137+
break()
138+
else()
139+
endif()
140+
endforeach()
141+
endif()
142+
143+
target_compile_definitions(${PROJECT_NAME}
144+
PUBLIC $<$<BOOL:${HAVE_EXECINFO_H}>:HAVE_EXEC_INFO_H>
145+
$<$<BOOL:${PCRE}>:USE_PCRE>
146+
$<$<AND:$<BOOL:${PCRE}>,$<BOOL:${HAVE_PCREPOSIX_H}>>:HAVE_PCREPOSIX_H>
147+
$<$<BOOL:${HAVE_REGEX_H}>:HAVE_REGEX_H>
148+
$<$<BOOL:${USE_GKREGEX}>:USE_GKREGEX>
149+
$<$<BOOL:${HAVE_GETLINE}>:HAVE_GETLINE>
150+
__thread=${TLS_NAME})
151+
152+
target_compile_options(${PROJECT_NAME}
153+
PUBLIC $<$<AND:$<BOOL:${GPROF}>,$<BOOL:${HAVE_GPROF_SUPPORT}>>:-pg>)
154+
155+
target_link_libraries(${PROJECT_NAME}
156+
PUBLIC $<$<BOOL:${OpenMP_C_FOUND}>:OpenMP::OpenMP_C>)
157+
158+
#-------------------------------------------------------------------------------
159+
# APPS configuration
160+
#-------------------------------------------------------------------------------
161+
if(GKLIB_BUILD_APPS)
162+
add_subdirectory("apps")
163+
endif()
164+
165+
#-------------------------------------------------------------------------------
166+
# PACKAGE configuration
167+
#-------------------------------------------------------------------------------
168+
# generate files
169+
configure_package_config_file(GKlibConfig.cmake.in cmake/GKlibConfig.cmake
170+
INSTALL_DESTINATION lib/cmake/GKlib)
171+
172+
write_basic_package_version_file(cmake/GKlibConfigVersion.cmake
173+
VERSION ${PROJECT_VERSION}
174+
COMPATIBILITY SameMajorVersion)
175+
176+
# install library
177+
install(TARGETS ${PROJECT_NAME} EXPORT GKlibTargets
178+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
179+
COMPONENT GKlib_Runtime
180+
NAMELINK_SKIP
181+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
182+
COMPONENT GKlib_Development
183+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
184+
185+
# The previous install() command is repeated here to distinguish installations
186+
# that include a namelink versus those that do not. Unfortunately, prior to
187+
# CMake 3.12, when the NAMELINK_COMPONENT property was introduced, this was
188+
# necessary to get the desired behavior.
189+
if(BUILD_SHARED_LIBS)
190+
install(TARGETS ${PROJECT_NAME}
191+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
192+
COMPONENT GKlib_Development
193+
NAMELINK_ONLY)
194+
endif()
195+
196+
# install header files
197+
install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/"
198+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
199+
COMPONENT GKlib_Development)
200+
201+
# install files necessary to use find_package() with GKlib
202+
install(EXPORT GKlibTargets
203+
FILE GKlibTargets.cmake
204+
NAMESPACE GKlib::
205+
DESTINATION lib/cmake/GKlib
206+
COMPONENT GKlib_Development)
207+
208+
install(
209+
FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/GKlibConfig.cmake
210+
${CMAKE_CURRENT_BINARY_DIR}/cmake/GKlibConfigVersion.cmake
211+
DESTINATION lib/cmake/GKlib
212+
COMPONENT GKlib_Development)

GKlibConfig.cmake.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include(${CMAKE_CURRENT_LIST_DIR}/GKlibTargets.cmake)

0 commit comments

Comments
 (0)