From fe3d086fa75a289d6e4085df6f855f4c88c8d7c2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 30 Nov 2017 08:14:27 -0500 Subject: [PATCH] Improve CMake build system New build options ----------------- * Add option BUILD_TESTING by default ON See https://cmake.org/cmake/help/v2.8.12/cmake.html#module:CTest * Simplify library type selection using standard option BUILD_SHARED_LIBS See https://cmake.org/cmake/help/v3.0/variable/BUILD_SHARED_LIBS.html yamlConfig.cmake ---------------- * Generate and install yamlConfig.cmake, yamlConfigVersion.cmake and yamlTargets.cmake * Bump CMake version and explicitly associate include dirs with targets See https://cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#include-directories-and-usage-requirements * Ensure building against libyaml using "find_package(yaml)" uses expected compile options: Set HAVE_CONFIG_H as private compile option, YAML_DECLARE_STATIC as public Testing ------- * Build all examples from "tests" directory CMake Best practices -------------------- * configure "config.h" based on version info found in CMakeLists.txt * Ensure buildsystem re-generation listing sources (best-practice) It is not recommended to use GLOB to collect a list of source files from the source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. See https://cmake.org/cmake/help/v3.8/command/file.html Compilation warnings -------------------- * Set _CRT_SECURE_NO_WARNINGS if building using VisualStudio This will avoid warnings like this one: ``` C:\projects\libyaml\tests\run-emitter.c(268): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ``` Continuous Integration ---------------------- * travis: Install CMake >= 3.x using scikit-ci-addons * Add comments to appveyor.yml and run-tests.sh --- .gitignore | 1 - .travis.yml | 21 ++++-- CMakeLists.txt | 162 +++++++++++++++++++++++++++++++++++++++---- Makefile.am | 2 +- appveyor.yml | 13 ++++ cmake/config.h.in | 4 ++ configure.ac | 2 +- tests/CMakeLists.txt | 25 +++++++ tests/run-tests.sh | 2 + win32/Makefile.am | 3 - win32/config.h | 4 -- yamlConfig.cmake.in | 16 +++++ 12 files changed, 224 insertions(+), 31 deletions(-) create mode 100644 cmake/config.h.in create mode 100644 tests/CMakeLists.txt delete mode 100644 win32/Makefile.am delete mode 100644 win32/config.h create mode 100644 yamlConfig.cmake.in diff --git a/.gitignore b/.gitignore index 5eb86f5..2bda964 100644 --- a/.gitignore +++ b/.gitignore @@ -60,4 +60,3 @@ tests/run-test-suite/src/libyaml-parser /tests/test-version /tests/test-version.log /tests/test-version.trs -/win32/Makefile diff --git a/.travis.yml b/.travis.yml index e789986..8140b72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,20 @@ -os: -- linux -- osx + +matrix: + include: + - os: linux + sudo: required + compiler: gcc + - os: linux + sudo: required + compiler: clang + - os: osx + compiler: gcc + - os: osx + compiler: clang language: c -compiler: -- clang -- gcc +before_install: +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pip install --user scikit-ci-addons==0.15.0; ci_addons travis/install_cmake 3.2.0; fi script: tests/run-tests.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index e47f5ef..5e85aef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ -# Minimal CMake project for building a static library under Windows. -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required(VERSION 3.0) project (yaml C) set (YAML_VERSION_MAJOR 0) @@ -8,21 +7,154 @@ set (YAML_VERSION_MINOR 1) set (YAML_VERSION_PATCH 7) set (YAML_VERSION_STRING "${YAML_VERSION_MAJOR}.${YAML_VERSION_MINOR}.${YAML_VERSION_PATCH}") -file (GLOB SRC src/*.c) +option(BUILD_SHARED_LIBS "Build libyaml as a shared library" OFF) -include_directories (include win32) -add_library (yaml SHARED ${SRC}) -set_target_properties(yaml PROPERTIES COMPILE_FLAGS "-DYAML_DECLARE_EXPORT -DHAVE_CONFIG_H") +# +# Output directories for a build tree +# +if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +endif() -add_library (yaml_static STATIC ${SRC}) -set_target_properties(yaml_static PROPERTIES COMPILE_FLAGS "-DYAML_DECLARE_STATIC -DHAVE_CONFIG_H") +# +# Install relative directories +# +if(NOT DEFINED INSTALL_LIB_DIR) + set(INSTALL_LIB_DIR lib) +endif() +if(NOT DEFINED INSTALL_BIN_DIR) + set(INSTALL_BIN_DIR bin) +endif() +if(NOT DEFINED INSTALL_INCLUDE_DIR) + set(INSTALL_INCLUDE_DIR include) +endif() +if(NOT DEFINED INSTALL_CMAKE_DIR) + set(INSTALL_CMAKE_DIR cmake) +endif() -add_executable (test-version tests/test-version.c) -target_link_libraries(test-version yaml) -add_test(NAME version COMMAND test-version) +# +# Build library +# +set(SRCS + src/api.c + src/dumper.c + src/emitter.c + src/loader.c + src/parser.c + src/reader.c + src/scanner.c + src/writer.c + ) -add_executable (test-reader tests/test-reader.c) -target_link_libraries(test-reader yaml) -add_test(NAME reader COMMAND test-reader) +set(config_h ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) +configure_file( + cmake/config.h.in + ${config_h} + ) -enable_testing() +add_library(yaml ${SRCS}) + +if(NOT BUILD_SHARED_LIBS) + set_target_properties(yaml + PROPERTIES OUTPUT_NAME yaml_static + ) +endif() + +set_target_properties(yaml + PROPERTIES DEFINE_SYMBOL YAML_DECLARE_EXPORT + ) + +target_compile_definitions(yaml + PRIVATE HAVE_CONFIG_H + PUBLIC + $<$>:YAML_DECLARE_STATIC> + $<$:_CRT_SECURE_NO_WARNINGS> + ) + +target_include_directories(yaml PUBLIC + $ + $ + $ + ) + +# +# Install rules +# +install( + FILES + include/yaml.h + ${config_h} + DESTINATION include COMPONENT Development + ) + +install( + TARGETS yaml + EXPORT yamlTargets + RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT Runtime + LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT Development + ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT Development + ) + +# +# Add tests +# +include(CTest) # This module defines BUILD_TESTING option +if(BUILD_TESTING) + add_subdirectory(tests) +endif() + +# +# Generate 'yamlConfig.cmake', 'yamlConfigVersion.cmake' and 'yamlTargets.cmake' +# +include(CMakePackageConfigHelpers) + +# Configure 'yamlConfig.cmake' for a build tree +set(CONFIG_DIR_CONFIG ${PROJECT_BINARY_DIR}) +set(config_file ${PROJECT_BINARY_DIR}/yamlConfig.cmake) +configure_package_config_file( + yamlConfig.cmake.in + ${config_file} + INSTALL_DESTINATION ${PROJECT_BINARY_DIR} + PATH_VARS CONFIG_DIR_CONFIG + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + +# Configure 'yamlTargets.cmake' for a build tree +export(TARGETS yaml + FILE ${PROJECT_BINARY_DIR}/yamlTargets.cmake + ) + +# Configure and install 'yamlConfig.cmake' for an install tree +set(CONFIG_DIR_CONFIG ${INSTALL_CMAKE_DIR}) +set(install_config_file ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yamlConfig.cmake ) +configure_package_config_file( + yamlConfig.cmake.in + ${install_config_file} + INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR} + PATH_VARS CONFIG_DIR_CONFIG + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) +install( + FILES ${install_config_file} + DESTINATION ${INSTALL_CMAKE_DIR} COMPONENT Development + ) + +# Configure and install 'yamlTargets.cmake' for an install tree +install(EXPORT yamlTargets + FILE yamlTargets.cmake + DESTINATION ${INSTALL_CMAKE_DIR} + COMPONENT Development + ) + +# Configure 'yamlConfigVersion.cmake' for a build tree +set(config_version_file ${PROJECT_BINARY_DIR}/yamlConfigVersion.cmake) +write_basic_package_version_file( + ${config_version_file} + VERSION ${YAML_VERSION_STRING} + COMPATIBILITY AnyNewerVersion +) +# ... and install for an install tree +install( + FILES ${config_version_file} + DESTINATION ${INSTALL_CMAKE_DIR} COMPONENT Development + ) diff --git a/Makefile.am b/Makefile.am index 6425b6b..d682892 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ## Run `./bootstrap` to generate the "Makefile.in" files in this directory and ## the "$SUBDIRS" subdirectories. -SUBDIRS = include src . tests win32 +SUBDIRS = include src . tests EXTRA_DIST = README LICENSE CMakeLists.txt doc/doxygen.cfg diff --git a/appveyor.yml b/appveyor.yml index 7922b4b..88f6e6a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,8 +5,21 @@ image: - Visual Studio 2013 build_script: + +# +# CMake based in-source build and tests using Visual Studio +# + +# Use 32-bit default generator ("Visual Studio 12 2013" or "Visual Studio 14 2015") - cmake . - cmake --build . --config release --clean-first - ctest -C release + +# +# Autoconf based in-source build and tests under Cygwin using gcc +# + +# 32-bit - C:\cygwin\bin\sh -c "export PATH=/usr/bin:/usr/local/bin:$PATH && ./bootstrap && ./configure && make && make test && make distclean" +# 64-bit - C:\cygwin64\bin\sh -c "export PATH=/usr/bin:/usr/local/bin:$PATH && ./bootstrap && ./configure && make && make test && make distclean" diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 0000000..51e2e24 --- /dev/null +++ b/cmake/config.h.in @@ -0,0 +1,4 @@ +#define YAML_VERSION_MAJOR @YAML_VERSION_MAJOR@ +#define YAML_VERSION_MINOR @YAML_VERSION_MINOR@ +#define YAML_VERSION_PATCH @YAML_VERSION_PATCH@ +#define YAML_VERSION_STRING "@YAML_VERSION_STRING@" diff --git a/configure.ac b/configure.ac index ba7a54e..75e40e5 100644 --- a/configure.ac +++ b/configure.ac @@ -67,7 +67,7 @@ AC_C_CONST AC_TYPE_SIZE_T # Define Makefiles. -AC_CONFIG_FILES([yaml-0.1.pc include/Makefile src/Makefile Makefile tests/Makefile win32/Makefile]) +AC_CONFIG_FILES([yaml-0.1.pc include/Makefile src/Makefile Makefile tests/Makefile]) # Generate the "configure" script. AC_OUTPUT diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..d10b424 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,25 @@ + +function(add_yaml_executable name) + add_executable(${name} ${name}.c) + target_link_libraries(${name} yaml) +endfunction() + +foreach(name IN ITEMS + example-deconstructor + example-deconstructor-alt + example-reformatter + example-reformatter-alt + run-dumper + run-emitter + run-loader + run-parser + run-scanner + test-reader + test-version + ) + add_yaml_executable(${name}) +endforeach() + +add_test(NAME version COMMAND test-version) +add_test(NAME reader COMMAND test-reader) + diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 3336900..f7276f2 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -3,12 +3,14 @@ set -e main() { + # Autoconf based in-source build and tests clean ./bootstrap ./configure make test-all + # CMake based in-source build and tests clean cmake . diff --git a/win32/Makefile.am b/win32/Makefile.am deleted file mode 100644 index 00cfe3b..0000000 --- a/win32/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ - -EXTRA_DIST = config.h - diff --git a/win32/config.h b/win32/config.h deleted file mode 100644 index 9ca2669..0000000 --- a/win32/config.h +++ /dev/null @@ -1,4 +0,0 @@ -#define YAML_VERSION_MAJOR 0 -#define YAML_VERSION_MINOR 1 -#define YAML_VERSION_PATCH 7 -#define YAML_VERSION_STRING "0.1.7" diff --git a/yamlConfig.cmake.in b/yamlConfig.cmake.in new file mode 100644 index 0000000..dd3f8ee --- /dev/null +++ b/yamlConfig.cmake.in @@ -0,0 +1,16 @@ +# Config file for the yaml library. +# +# It defines the following variables: +# yaml_LIBRARIES - libraries to link against + +@PACKAGE_INIT@ + +set_and_check(yaml_TARGETS "@PACKAGE_CONFIG_DIR_CONFIG@/yamlTargets.cmake") + +if(NOT yaml_TARGETS_IMPORTED) + set(yaml_TARGETS_IMPORTED 1) + include(${yaml_TARGETS}) +endif() + +set(yaml_LIBRARIES yaml) + -- 2.45.0