WCDH: Make it possible to generate multiple files.
Extend the write_compiler_detection_header interface to allow specifying a location for supplementary files, and getting the list of resulting files as a variable.
This commit is contained in:
parent
2ed0088b2a
commit
4cf5179c77
|
@ -11,6 +11,7 @@
|
|||
# write_compiler_detection_header(
|
||||
# FILE <file>
|
||||
# PREFIX <prefix>
|
||||
# [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>]
|
||||
# COMPILERS <compiler> [...]
|
||||
# FEATURES <feature> [...]
|
||||
# [VERSION <version>]
|
||||
|
@ -21,6 +22,33 @@
|
|||
# The ``write_compiler_detection_header`` function generates the
|
||||
# file ``<file>`` with macros which all have the prefix ``<prefix>``.
|
||||
#
|
||||
# By default, all content is written directly to the ``<file>``. The
|
||||
# ``OUTPUT_FILES_VAR`` may be specified to cause the compiler-specific
|
||||
# content to be written to separate files. The separate files are then
|
||||
# available in the ``<output_files_var>`` and may be consumed by the caller
|
||||
# for installation for example. The ``OUTPUT_DIR`` specifies a relative
|
||||
# path from the main ``<file>`` to the compiler-specific files. For example:
|
||||
#
|
||||
# .. code-block:: cmake
|
||||
#
|
||||
# write_compiler_detection_header(
|
||||
# FILE climbingstats_compiler_detection.h
|
||||
# PREFIX ClimbingStats
|
||||
# OUTPUT_FILES_VAR support_files
|
||||
# OUTPUT_DIR compilers
|
||||
# COMPILERS GNU Clang
|
||||
# FEATURES cxx_variadic_templates
|
||||
# )
|
||||
# install(FILES
|
||||
# ${CMAKE_CURRENT_BINARY_DIR}/climbingstats_compiler_detection.h
|
||||
# DESTINATION include
|
||||
# )
|
||||
# install(FILES
|
||||
# ${support_files}
|
||||
# DESTINATION include/compilers
|
||||
# )
|
||||
#
|
||||
#
|
||||
# ``VERSION`` may be used to specify the API version to be generated.
|
||||
# Future versions of CMake may introduce alternative APIs. A given
|
||||
# API is selected by any ``<version>`` value greater than or equal
|
||||
|
@ -220,7 +248,7 @@ function(write_compiler_detection_header
|
|||
message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.")
|
||||
endif()
|
||||
set(options)
|
||||
set(oneValueArgs VERSION EPILOG PROLOG)
|
||||
set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR)
|
||||
set(multiValueArgs COMPILERS FEATURES)
|
||||
cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
|
@ -255,6 +283,35 @@ function(write_compiler_detection_header
|
|||
message(FATAL_ERROR "${err}")
|
||||
endif()
|
||||
|
||||
if(_WCD_OUTPUT_FILES_VAR)
|
||||
if(NOT _WCD_OUTPUT_DIR)
|
||||
message(FATAL_ERROR "If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.")
|
||||
endif()
|
||||
endif()
|
||||
if(_WCD_OUTPUT_DIR)
|
||||
if(NOT _WCD_OUTPUT_FILES_VAR)
|
||||
message(FATAL_ERROR "If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.")
|
||||
endif()
|
||||
get_filename_component(main_file_dir ${file_arg} DIRECTORY)
|
||||
if (NOT IS_ABSOLUTE ${main_file_dir})
|
||||
set(main_file_dir "${CMAKE_CURRENT_BINARY_DIR}/${main_file_dir}")
|
||||
endif()
|
||||
if (NOT IS_ABSOLUTE ${_WCD_OUTPUT_DIR})
|
||||
set(_WCD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_WCD_OUTPUT_DIR}")
|
||||
endif()
|
||||
get_filename_component(out_file_dir ${_WCD_OUTPUT_DIR} ABSOLUTE)
|
||||
string(FIND ${out_file_dir} ${main_file_dir} idx)
|
||||
if (NOT idx EQUAL 0)
|
||||
message(FATAL_ERROR "The compiler-specific output directory must be within the same directory as the main file.")
|
||||
endif()
|
||||
|
||||
if (main_file_dir STREQUAL out_file_dir)
|
||||
unset(_WCD_OUTPUT_DIR)
|
||||
else()
|
||||
string(REPLACE "${main_file_dir}/" "" _WCD_OUTPUT_DIR "${out_file_dir}/")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(compilers
|
||||
GNU
|
||||
Clang
|
||||
|
@ -314,6 +371,14 @@ function(write_compiler_detection_header
|
|||
endforeach()
|
||||
list(REMOVE_DUPLICATES _langs)
|
||||
|
||||
if(_WCD_OUTPUT_FILES_VAR)
|
||||
get_filename_component(main_file_name ${file_arg} NAME)
|
||||
set(compiler_file_content_
|
||||
"#ifndef ${prefix_arg}_COMPILER_DETECTION_H
|
||||
# error This file may only be included from ${main_file_name}
|
||||
#endif\n")
|
||||
endif()
|
||||
|
||||
foreach(_lang ${_langs})
|
||||
|
||||
get_property(known_features GLOBAL PROPERTY CMAKE_${_lang}_KNOWN_FEATURES)
|
||||
|
@ -340,7 +405,19 @@ function(write_compiler_detection_header
|
|||
foreach(compiler ${_WCD_COMPILERS})
|
||||
_load_compiler_variables(${compiler} ${_lang} ${${_lang}_features})
|
||||
set(file_content "${file_content}\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n")
|
||||
set(file_content "${file_content}
|
||||
|
||||
if(_WCD_OUTPUT_FILES_VAR)
|
||||
set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}.h")
|
||||
set(file_content "${file_content}\n# include \"${compile_file_name}\"\n")
|
||||
endif()
|
||||
|
||||
if(_WCD_OUTPUT_FILES_VAR)
|
||||
set(compiler_file_content compiler_file_content_${compiler})
|
||||
else()
|
||||
set(compiler_file_content file_content)
|
||||
endif()
|
||||
|
||||
set(${compiler_file_content} "${${compiler_file_content}}
|
||||
# if !(${_cmake_oldestSupported_${compiler}})
|
||||
# error Unsupported compiler version
|
||||
# endif\n")
|
||||
|
@ -354,7 +431,7 @@ function(write_compiler_detection_header
|
|||
set(MACRO_HEX)
|
||||
endif()
|
||||
string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY)
|
||||
set(file_content "${file_content}${VERSION_BLOCK}\n")
|
||||
set(${compiler_file_content} "${${compiler_file_content}}${VERSION_BLOCK}\n")
|
||||
set(PREFIX)
|
||||
set(MACRO_DEC)
|
||||
set(MACRO_HEX)
|
||||
|
@ -370,7 +447,7 @@ function(write_compiler_detection_header
|
|||
set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n")
|
||||
set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n")
|
||||
endif()
|
||||
set(file_content "${file_content}${_define_item}")
|
||||
set(${compiler_file_content} "${${compiler_file_content}}${_define_item}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
if(pp_if STREQUAL "elif")
|
||||
|
@ -522,6 +599,22 @@ function(write_compiler_detection_header
|
|||
|
||||
endforeach()
|
||||
|
||||
if(_WCD_OUTPUT_FILES_VAR)
|
||||
foreach(compiler ${_WCD_COMPILERS})
|
||||
set(CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_}")
|
||||
set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}${compiler_file_content_${compiler}}")
|
||||
|
||||
set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}.h")
|
||||
set(full_path "${main_file_dir}/${compile_file_name}")
|
||||
list(APPEND ${_WCD_OUTPUT_FILES_VAR} ${full_path})
|
||||
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
|
||||
"${full_path}"
|
||||
@ONLY
|
||||
)
|
||||
endforeach()
|
||||
set(${_WCD_OUTPUT_FILES_VAR} ${${_WCD_OUTPUT_FILES_VAR}} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if (_WCD_EPILOG)
|
||||
set(file_content "${file_content}\n${_WCD_EPILOG}\n")
|
||||
endif()
|
||||
|
|
|
@ -67,6 +67,22 @@ add_executable(WriteCompilerDetectionHeader main.cpp)
|
|||
set_property(TARGET WriteCompilerDetectionHeader PROPERTY CXX_STANDARD 98)
|
||||
set_defines(WriteCompilerDetectionHeader "${true_defs}" "${false_defs}")
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/multi_file_compiler_detection.h"
|
||||
PREFIX MULTI
|
||||
OUTPUT_FILES_VAR multi_files
|
||||
OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/compiler_support"
|
||||
COMPILERS GNU Clang
|
||||
VERSION 3.1
|
||||
FEATURES
|
||||
${cxx_known_features} ${c_known_features}
|
||||
)
|
||||
|
||||
add_executable(multi_files multi_files.cpp)
|
||||
set_property(TARGET multi_files PROPERTY CXX_STANDARD 98)
|
||||
target_include_directories(multi_files PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files)
|
||||
set_defines(multi_files "${true_defs}" "${false_defs}")
|
||||
|
||||
if(MSVC)
|
||||
return() # MSVC has only one mode.
|
||||
endif()
|
||||
|
@ -86,3 +102,8 @@ endif()
|
|||
add_executable(WriteCompilerDetectionHeader_11 main.cpp)
|
||||
set_property(TARGET WriteCompilerDetectionHeader_11 PROPERTY CXX_STANDARD 11)
|
||||
set_defines(WriteCompilerDetectionHeader_11 "${true_defs}" "${false_defs}")
|
||||
|
||||
add_executable(multi_files_11 multi_files.cpp)
|
||||
set_property(TARGET multi_files_11 PROPERTY CXX_STANDARD 11)
|
||||
target_include_directories(multi_files_11 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files)
|
||||
set_defines(multi_files_11 "${true_defs}" "${false_defs}")
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#define JOIN_IMPL(A, B) A ## B
|
||||
#define JOIN(A, B) JOIN_IMPL(A, B)
|
||||
|
||||
#define CHECK(FEATURE) (JOIN(PREFIX, JOIN(_COMPILER_, FEATURE)) == JOIN(EXPECTED_COMPILER_, FEATURE))
|
||||
|
||||
#if !CHECK(CXX_DELEGATING_CONSTRUCTORS)
|
||||
#error cxx_delegating_constructors expected availability did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(CXX_VARIADIC_TEMPLATES)
|
||||
#error cxx_variadic_templates expected availability did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(VERSION_MAJOR)
|
||||
#error Compiler major version did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(VERSION_MINOR)
|
||||
#error Compiler minor version did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(VERSION_PATCH)
|
||||
#error Compiler patch version did not match.
|
||||
#endif
|
|
@ -1,29 +1,8 @@
|
|||
|
||||
#include "test_compiler_detection.h"
|
||||
|
||||
#define JOIN_IMPL(A, B) A ## B
|
||||
#define JOIN(A, B) JOIN_IMPL(A, B)
|
||||
#define CHECK(FEATURE) (JOIN(TEST_COMPILER_, FEATURE) == JOIN(EXPECTED_COMPILER_, FEATURE))
|
||||
|
||||
#if !CHECK(CXX_DELEGATING_CONSTRUCTORS)
|
||||
#error cxx_delegating_constructors expected availability did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(CXX_VARIADIC_TEMPLATES)
|
||||
#error cxx_variadic_templates expected availability did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(VERSION_MAJOR)
|
||||
#error Compiler major version did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(VERSION_MINOR)
|
||||
#error Compiler minor version did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(VERSION_PATCH)
|
||||
#error Compiler patch version did not match.
|
||||
#endif
|
||||
#define PREFIX TEST
|
||||
#include "compile_tests.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#include "multi_file_compiler_detection.h"
|
||||
|
||||
#define PREFIX MULTI
|
||||
#include "compile_tests.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
The compiler-specific output directory must be within the same directory as
|
||||
the main file.
|
||||
Call Stack \(most recent call first\):
|
||||
MultiBadOutDir.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/dir/somefile"
|
||||
PREFIX Pref
|
||||
OUTPUT_FILES_VAR outfiles
|
||||
OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
COMPILERS GNU
|
||||
VERSION 3.1
|
||||
FEATURES cxx_auto_type
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.
|
||||
Call Stack \(most recent call first\):
|
||||
MultiNoOutFileVar.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX Pref
|
||||
OUTPUT_DIR outfiles
|
||||
COMPILERS GNU
|
||||
VERSION 3.1
|
||||
FEATURES cxx_auto_type
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.
|
||||
Call Stack \(most recent call first\):
|
||||
MultiNoOutdir.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX Pref
|
||||
OUTPUT_FILES_VAR outfiles
|
||||
COMPILERS GNU
|
||||
VERSION 3.1
|
||||
FEATURES cxx_auto_type
|
||||
)
|
|
@ -12,3 +12,7 @@ run_cmake(InvalidFeature)
|
|||
run_cmake(InvalidCXXFeature)
|
||||
run_cmake(EmptyPrefix)
|
||||
run_cmake(InvalidPrefix)
|
||||
run_cmake(MultiNoOutdir)
|
||||
run_cmake(MultiNoOutFileVar)
|
||||
set(NO_CACHE TRUE)
|
||||
run_cmake(MultiBadOutDir)
|
||||
|
|
Loading…
Reference in New Issue