diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2021-11-08 09:23:52 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2021-11-08 09:23:52 +0300 |
commit | 3bce6bcc1edba58e30f48322953486ea86ef4f21 (patch) | |
tree | 1e8f3d04b9b7a93311d7dbc1d44c80cd0692b19f | |
parent | cf55946ee97110ea6cf8841d54febf3a3d000d0e (diff) | |
download | libatomic_ops-3bce6bcc1edba58e30f48322953486ea86ef4f21.tar.gz |
Support build with CMake
* CMakeLists.txt: New file.
* Config.cmake.in: Likewise.
* Makefile.am (EXTRA_DIST): Add CMakeLists.txt, Config.cmake.in.
* README.md (Installation and Usage): Describe shortly how to build
the package with CMake (and how to disable GPL code in case of CMake).
* README_win32.txt: Likewise.
* README_details.txt: Document cmake-based build.
-rw-r--r-- | CMakeLists.txt | 353 | ||||
-rw-r--r-- | Config.cmake.in | 5 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | README_details.txt | 15 | ||||
-rw-r--r-- | README_win32.txt | 1 |
6 files changed, 380 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c5d833e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,353 @@ +# +# Copyright (c) 2021 Ivan Maidanski +## +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +## + +cmake_minimum_required(VERSION 3.1) + +set(PACKAGE_VERSION 7.7.0) +# Version must match that in AC_INIT of configure.ac and that in README. +# Version must conform to: [0-9]+[.][0-9]+[.][0-9]+ + +# Info (current:revision:age) for the Libtool versioning system. +# These values should match those in src/Makefile.am. +set(LIBATOMIC_OPS_VER_INFO 2:1:1) +set(LIBATOMIC_OPS_GPL_VER_INFO 2:2:1) + +project(atomic_ops C) + +include(CheckCCompilerFlag) +include(CheckFunctionExists) +include(CMakePackageConfigHelpers) +include(CTest) +include(GNUInstallDirs) + +# Customize the build by passing "-D<option_name>=ON|OFF" in the command line. +option(BUILD_SHARED_LIBS "Build shared libraries" OFF) +option(build_tests "Build tests" OFF) +option(enable_assertions "Enable assertion checking" OFF) +option(enable_werror "Treat warnings as errors" OFF) +option(enable_atomic_intrinsics "Use GCC atomic intrinsics" ON) +option(enable_docs "Build and install documentation" ON) +option(enable_gpl "Build atomic_ops_gpl library" ON) +option(install_headers "Install header and pkg-config metadata files" ON) + +# Convert VER_INFO values to [SO]VERSION ones. +if (BUILD_SHARED_LIBS) + # atomic_ops: + string(REGEX REPLACE "(.+):.+:.+" "\\1" ao_cur ${LIBATOMIC_OPS_VER_INFO}) + string(REGEX REPLACE ".+:(.+):.+" "\\1" ao_rev ${LIBATOMIC_OPS_VER_INFO}) + string(REGEX REPLACE ".+:.+:(.+)$" "\\1" ao_age ${LIBATOMIC_OPS_VER_INFO}) + math(EXPR AO_SOVERSION "${ao_cur} - ${ao_age}") + set(AO_VERSION_PROP "${AO_SOVERSION}.${ao_age}.${ao_rev}") + message(STATUS "AO_VERSION_PROP = ${AO_VERSION_PROP}") + # atomic_ops_gpl: + string(REGEX REPLACE "(.+):.+:.+" "\\1" ao_gpl_cur + ${LIBATOMIC_OPS_GPL_VER_INFO}) + string(REGEX REPLACE ".+:(.+):.+" "\\1" ao_gpl_rev + ${LIBATOMIC_OPS_GPL_VER_INFO}) + string(REGEX REPLACE ".+:.+:(.+)$" "\\1" ao_gpl_age + ${LIBATOMIC_OPS_GPL_VER_INFO}) + math(EXPR AO_GPL_SOVERSION "${ao_gpl_cur} - ${ao_gpl_age}") + set(AO_GPL_VERSION_PROP "${AO_GPL_SOVERSION}.${ao_gpl_age}.${ao_gpl_rev}") + message(STATUS "AO_GPL_VERSION_PROP = ${AO_GPL_VERSION_PROP}") +endif(BUILD_SHARED_LIBS) + +# Output all warnings. +if (BORLAND) + # All warnings except for particular ones. + add_compile_options(/w) #?? /w-pro /w-aus /w-par /w-ccc /w-inl /w-rch +elseif (MSVC) + # All warnings but ignoring "conditional expression is constant" ones. + add_compile_options(/W4 /wd4127) +elseif (WATCOM) + add_compile_options(/wx) +else() + # TODO: add -[W]pedantic -Wno-long-long + add_compile_options(-Wall -Wextra) +endif() + +include_directories(src) + +find_package(Threads REQUIRED) +message(STATUS "Thread library: ${CMAKE_THREAD_LIBS_INIT}") +include_directories(${Threads_INCLUDE_DIR}) +set(THREADDLLIBS_LIST ${CMAKE_THREAD_LIBS_INIT}) + +if (CMAKE_USE_PTHREADS_INIT) + # Required define if using POSIX threads. + add_definitions("-D_REENTRANT") +else() + # No pthreads library available. + add_definitions("-DAO_NO_PTHREADS") +endif() + +if (NOT enable_assertions) + # Define to disable assertion checking. + add_definitions("-DNDEBUG") +endif() + +if (NOT enable_atomic_intrinsics) + # Define to avoid GCC atomic intrinsics even if available. + add_definitions("-DAO_DISABLE_GCC_ATOMICS") +endif() + +# AO API symbols export control. +if (BUILD_SHARED_LIBS) + add_definitions("-DAO_DLL") +endif() + +if (enable_werror) + if (BORLAND) + add_compile_options(/w!) + elseif (MSVC) + add_compile_options(/WX) + elseif (WATCOM) + add_compile_options(/we) + else() + add_compile_options(-Werror) + endif() +endif(enable_werror) + +# Extra user-defined flags to pass to the C compiler. +if (DEFINED CFLAGS_EXTRA) + add_compile_options(${CFLAGS_EXTRA}) +endif() + +set(SRC src/atomic_ops.c) + +if (CMAKE_C_COMPILER_ID STREQUAL "SunPro") + # SunCC compiler on SunOS (Solaris). + set(SRC ${SRC} src/atomic_ops_sysdeps.S) +endif() + +add_library(atomic_ops ${SRC}) +target_link_libraries(atomic_ops PRIVATE ${THREADDLLIBS_LIST}) +target_include_directories(atomic_ops INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>" + "$<INSTALL_INTERFACE:include>") + +if (enable_gpl) + check_function_exists(mmap HAVE_MMAP) + if (HAVE_MMAP) + add_definitions("-DHAVE_MMAP") + endif() + set(AO_GPL_SRC src/atomic_ops_malloc.c src/atomic_ops_stack.c) + add_library(atomic_ops_gpl ${AO_GPL_SRC}) + target_link_libraries(atomic_ops_gpl PRIVATE atomic_ops) + target_include_directories(atomic_ops_gpl INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>" + "$<INSTALL_INTERFACE:include>") + if (BUILD_SHARED_LIBS) + set_property(TARGET atomic_ops_gpl PROPERTY VERSION ${AO_GPL_VERSION_PROP}) + set_property(TARGET atomic_ops_gpl PROPERTY SOVERSION ${AO_GPL_SOVERSION}) + endif() + install(TARGETS atomic_ops_gpl EXPORT Atomic_opsTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") +endif(enable_gpl) + +if (BUILD_SHARED_LIBS) + check_c_compiler_flag(-Wl,--no-undefined HAVE_FLAG_WL_NO_UNDEFINED) + if (HAVE_FLAG_WL_NO_UNDEFINED) + # Declare that the libraries do not refer to external symbols. + # TODO: use add_link_options() when cmake_minimum_required > 3.13 + target_link_libraries(atomic_ops PRIVATE -Wl,--no-undefined) + if (enable_gpl) + target_link_libraries(atomic_ops_gpl PRIVATE -Wl,--no-undefined) + endif(enable_gpl) + endif() + set_property(TARGET atomic_ops PROPERTY VERSION ${AO_VERSION_PROP}) + set_property(TARGET atomic_ops PROPERTY SOVERSION ${AO_SOVERSION}) +endif(BUILD_SHARED_LIBS) + +install(TARGETS atomic_ops EXPORT Atomic_opsTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + +if (install_headers) + install(FILES src/atomic_ops.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + if (enable_gpl) + install(FILES src/atomic_ops_malloc.h + src/atomic_ops_stack.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + endif() + + install(FILES src/atomic_ops/ao_version.h + src/atomic_ops/generalize-arithm.h + src/atomic_ops/generalize-small.h + src/atomic_ops/generalize.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops") + + install(FILES src/atomic_ops/sysdeps/all_acquire_release_volatile.h + src/atomic_ops/sysdeps/all_aligned_atomic_load_store.h + src/atomic_ops/sysdeps/all_atomic_load_store.h + src/atomic_ops/sysdeps/all_atomic_only_load.h + src/atomic_ops/sysdeps/ao_t_is_int.h + src/atomic_ops/sysdeps/emul_cas.h + src/atomic_ops/sysdeps/generic_pthread.h + src/atomic_ops/sysdeps/ordered.h + src/atomic_ops/sysdeps/ordered_except_wr.h + src/atomic_ops/sysdeps/read_ordered.h + src/atomic_ops/sysdeps/standard_ao_double_t.h + src/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h + src/atomic_ops/sysdeps/test_and_set_t_is_char.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps") + + install(FILES src/atomic_ops/sysdeps/armcc/arm_v6.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/armcc") + install(FILES src/atomic_ops/sysdeps/gcc/aarch64.h + src/atomic_ops/sysdeps/gcc/alpha.h + src/atomic_ops/sysdeps/gcc/arm.h + src/atomic_ops/sysdeps/gcc/avr32.h + src/atomic_ops/sysdeps/gcc/cris.h + src/atomic_ops/sysdeps/gcc/generic-arithm.h + src/atomic_ops/sysdeps/gcc/generic-small.h + src/atomic_ops/sysdeps/gcc/generic.h + src/atomic_ops/sysdeps/gcc/hexagon.h + src/atomic_ops/sysdeps/gcc/hppa.h + src/atomic_ops/sysdeps/gcc/ia64.h + src/atomic_ops/sysdeps/gcc/m68k.h + src/atomic_ops/sysdeps/gcc/mips.h + src/atomic_ops/sysdeps/gcc/powerpc.h + src/atomic_ops/sysdeps/gcc/riscv.h + src/atomic_ops/sysdeps/gcc/s390.h + src/atomic_ops/sysdeps/gcc/sh.h + src/atomic_ops/sysdeps/gcc/sparc.h + src/atomic_ops/sysdeps/gcc/tile.h + src/atomic_ops/sysdeps/gcc/x86.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/gcc") + + install(FILES src/atomic_ops/sysdeps/hpc/hppa.h + src/atomic_ops/sysdeps/hpc/ia64.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/hpc") + install(FILES src/atomic_ops/sysdeps/ibmc/powerpc.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/ibmc") + install(FILES src/atomic_ops/sysdeps/icc/ia64.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/icc") + + install(FILES src/atomic_ops/sysdeps/loadstore/acquire_release_volatile.h + src/atomic_ops/sysdeps/loadstore/atomic_load.h + src/atomic_ops/sysdeps/loadstore/atomic_store.h + src/atomic_ops/sysdeps/loadstore/char_acquire_release_volatile.h + src/atomic_ops/sysdeps/loadstore/char_atomic_load.h + src/atomic_ops/sysdeps/loadstore/char_atomic_store.h + src/atomic_ops/sysdeps/loadstore/double_atomic_load_store.h + src/atomic_ops/sysdeps/loadstore/int_acquire_release_volatile.h + src/atomic_ops/sysdeps/loadstore/int_atomic_load.h + src/atomic_ops/sysdeps/loadstore/int_atomic_store.h + src/atomic_ops/sysdeps/loadstore/ordered_loads_only.h + src/atomic_ops/sysdeps/loadstore/ordered_stores_only.h + src/atomic_ops/sysdeps/loadstore/short_acquire_release_volatile.h + src/atomic_ops/sysdeps/loadstore/short_atomic_load.h + src/atomic_ops/sysdeps/loadstore/short_atomic_store.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/loadstore") + + install(FILES src/atomic_ops/sysdeps/msftc/arm.h + src/atomic_ops/sysdeps/msftc/arm64.h + src/atomic_ops/sysdeps/msftc/common32_defs.h + src/atomic_ops/sysdeps/msftc/x86.h + src/atomic_ops/sysdeps/msftc/x86_64.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/msftc") + install(FILES src/atomic_ops/sysdeps/sunc/sparc.h + src/atomic_ops/sysdeps/sunc/x86.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/atomic_ops/sysdeps/sunc") + + # Provide pkg-config metadata. + set(prefix "${CMAKE_INSTALL_PREFIX}") + set(exec_prefix \${prefix}) + set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}") + set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}") + string(REPLACE ";" " " THREADDLLIBS "${THREADDLLIBS_LIST}") + # PACKAGE_VERSION is defined above. + configure_file(pkgconfig/atomic_ops.pc.in pkgconfig/atomic_ops.pc @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/atomic_ops.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + # TODO: handle atomic_ops-uninstalled.pc.in +endif(install_headers) + +if (build_tests) + add_executable(test_atomic tests/test_atomic.c) + target_link_libraries(test_atomic PRIVATE atomic_ops ${THREADDLLIBS_LIST}) + add_test(NAME test_atomic COMMAND test_atomic) + + add_executable(test_atomic_generalized tests/test_atomic.c) + target_compile_options(test_atomic_generalized + PRIVATE -DAO_PREFER_GENERALIZED -DAO_TEST_EMULATION) + target_link_libraries(test_atomic_generalized + PRIVATE atomic_ops ${THREADDLLIBS_LIST}) + add_test(NAME test_atomic_generalized COMMAND test_atomic_generalized) + + if (CMAKE_USE_PTHREADS_INIT) + add_executable(test_atomic_pthreads tests/test_atomic.c) + target_compile_options(test_atomic_pthreads PRIVATE -DAO_USE_PTHREAD_DEFS) + target_link_libraries(test_atomic_pthreads + PRIVATE atomic_ops ${THREADDLLIBS_LIST}) + add_test(NAME test_atomic_pthreads COMMAND test_atomic_pthreads) + endif() + + if (enable_gpl) + add_executable(test_stack tests/test_stack.c) + target_link_libraries(test_stack + PRIVATE atomic_ops atomic_ops_gpl ${THREADDLLIBS_LIST}) + add_test(NAME test_stack COMMAND test_stack) + + add_executable(test_malloc tests/test_malloc.c) + target_link_libraries(test_malloc + PRIVATE atomic_ops atomic_ops_gpl ${THREADDLLIBS_LIST}) + add_test(NAME test_malloc COMMAND test_malloc) + endif() +endif(build_tests) + +if (enable_docs) + install(FILES AUTHORS LICENSING.txt README.md + README_details.txt README_win32.txt + DESTINATION "${CMAKE_INSTALL_DOCDIR}") + if (enable_gpl) + install(FILES COPYING README_malloc.txt README_stack.txt + DESTINATION "${CMAKE_INSTALL_DOCDIR}") + endif() +endif(enable_docs) + +# CMake config/targets files. +install(EXPORT Atomic_opsTargets FILE Atomic_opsTargets.cmake + NAMESPACE Atomic_ops:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/atomic_ops") + +configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/Atomic_opsConfig.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/atomic_ops" + NO_SET_AND_CHECK_MACRO) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/Atomic_opsConfigVersion.cmake" + VERSION "${PACKAGE_VERSION}" COMPATIBILITY AnyNewerVersion) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Atomic_opsConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/Atomic_opsConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/atomic_ops") + +export(EXPORT Atomic_opsTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/Atomic_opsTargets.cmake") diff --git a/Config.cmake.in b/Config.cmake.in new file mode 100644 index 0000000..47e60a0 --- /dev/null +++ b/Config.cmake.in @@ -0,0 +1,5 @@ +# The Atomic_ops CMake configuration file. + +@PACKAGE_INIT@ +include("${CMAKE_CURRENT_LIST_DIR}/Atomic_opsTargets.cmake") +check_required_components(atomic_ops) diff --git a/Makefile.am b/Makefile.am index 1b110a1..6756d2c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ dist_doc_DATA += COPYING README_malloc.txt README_stack.txt endif endif -EXTRA_DIST = autogen.sh +EXTRA_DIST = autogen.sh CMakeLists.txt Config.cmake.in ## TODO: After migration to autoconf-1.13+, remove check-nolink definition ## from this Makefile.am and add AM_EXTRA_RECURSIVE_TARGETS([check-nolink]) @@ -63,6 +63,9 @@ directory should work. For a more customized build, see the output of `./configure --help`. To build it from the development repository, `./autogen.sh` should be executed first. +Alternatively, CMake could be use to build this package, e.g. +`cmake . && cmake --build .` in this directory should work. + Note that much of the content of this library is in the header files. However, two small libraries are built and installed: @@ -74,7 +77,9 @@ However, two small libraries are built and installed: * `libatomic_ops_gpl.a` contains some higher level facilities. This code is currently covered by the GPL. The contents currently correspond to the headers `atomic_ops_malloc.h` and `atomic_ops_stack.h`. Not built and - not installed if `--disable-gpl` option is passed to `configure`. + not installed if `--disable-gpl` option is passed to `configure` (or if + `-Denable_gpl=OFF` option is passed to `cmake` if the latter is used to + build the package). ## Platform Specific Notes diff --git a/README_details.txt b/README_details.txt index 8f5c137..43f2531 100644 --- a/README_details.txt +++ b/README_details.txt @@ -7,7 +7,20 @@ but the tests are much more likely to pass in the presence of serious problems. 1) Type ./configure --prefix=<install dir>; make; make check in the directory containing unpacked source. The usual GNU build machinery is used, except that only static, but position-independent, libraries -are normally built. On Windows, read README_win32.txt instead. +are normally built. On Windows, follow README_win32.txt to use +src/Makefile.msft instead of the above sequence. + +Alternatively, the libraries could be built with CMake, even for Windows, +like this: +> mkdir out +> cd out +> cmake -Dbuild_tests=ON .. +> cmake --build . --config Release +> ctest --build-config Release + +The available options in the CMake script to customize the build is roughly +the same as those in the configure one, please see the exact option list in +CMakeLists.txt file. 2) Applications should include atomic_ops.h. Nearly all operations are implemented by header files included from it. It is sometimes diff --git a/README_win32.txt b/README_win32.txt index 0006e6b..40735e7 100644 --- a/README_win32.txt +++ b/README_win32.txt @@ -7,6 +7,7 @@ To build and test the package: 2) Go to the src directory in the distribution and run "nmake -f Makefile.msft check". This should build atomic_ops.lib and atomic_ops_gpl.lib, and execute some tests. +Alternatively, CMake could be used (e.g., see how to in README_details.txt). To compile applications, you will need to retain or copy the following pieces from the resulting src directory contents: |