mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-21 08:47:42 +02:00
Discover Boost test cases automatically after build
This adds a global fixture that can parse an additional argument to the test executables (`--generate_ctest_config`). When run by CMake during build, this generates a CTest script containing all the tests and their properties. An additional decorator, that defines CTest properties for a test case or suite that will be added to the tests during config generation. This version needs no hacks, no huge CMake scripts, just a bit of additional C++ code that iterates over all test-cases and collects the information CTest needs. One caveat is still that this does not work with cross-compilation, which probably isn't an issue to begin with, but there are also ways to fix that if necessary.
This commit is contained in:
parent
38ea1bb39c
commit
b4681b10ec
@ -1,7 +1,7 @@
|
||||
# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+
|
||||
|
||||
# CMake 3.8 is required, CMake policy compatibility was verified up to 3.17.
|
||||
cmake_minimum_required(VERSION 3.8...3.17)
|
||||
# CMake 3.17 is required, CMake policy compatibility was verified up to 3.17.
|
||||
cmake_minimum_required(VERSION 3.17...3.17)
|
||||
set(BOOST_MIN_VERSION "1.66.0")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
21
cmake/DiscoverBoostTests.cmake
Normal file
21
cmake/DiscoverBoostTests.cmake
Normal file
@ -0,0 +1,21 @@
|
||||
# Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+
|
||||
|
||||
# - Discover tests defined in the Boost.Test executable target
|
||||
#
|
||||
# Boost.Test executables should be defined like any other CMake executable target.
|
||||
# Then, this function can be used on the executable target to discover all the unit
|
||||
# tests in that executable.
|
||||
# This relies on the additional commandline argument added in 'test/test-ctest.hpp'
|
||||
function(target_discover_boost_tests target)
|
||||
set(testfile "${CMAKE_CURRENT_BINARY_DIR}/${target}_tests.cmake")
|
||||
set(args -- --generate_ctest_config "${testfile}")
|
||||
string(REPLACE ";" "$<SEMICOLON>" test "${args}")
|
||||
|
||||
add_custom_command(TARGET "${target}" POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -DCMD=$<TARGET_FILE:${target}> -DARGS="${test}" -P "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExecuteCommandQuietly.cmake"
|
||||
)
|
||||
|
||||
set_property(DIRECTORY
|
||||
APPEND PROPERTY TEST_INCLUDE_FILES "${testfile}"
|
||||
)
|
||||
endfunction()
|
3
cmake/ExecuteCommandQuietly.cmake
Normal file
3
cmake/ExecuteCommandQuietly.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
# Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+
|
||||
|
||||
execute_process(COMMAND "${CMD}" ${ARGS} OUTPUT_QUIET)
|
17
test/BoostTestConfig.h.in
Normal file
17
test/BoostTestConfig.h.in
Normal file
@ -0,0 +1,17 @@
|
||||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#pragma once
|
||||
|
||||
// This will only be defined if cmake couldn't find a static or dynamic library to link against.
|
||||
#cmakedefine BOOST_TEST_USE_INCLUDED
|
||||
|
||||
// Only one file needs to include the implementation files
|
||||
#if defined(BOOST_TEST_USE_INCLUDED) && defined(TEST_INCLUDE_IMPLEMENTATION)
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#else
|
||||
|
||||
//If a dynamic library was found, this will be defined before including the header.
|
||||
#cmakedefine BOOST_TEST_DYN_LINK
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#endif
|
@ -1,8 +1,43 @@
|
||||
# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+
|
||||
|
||||
include(BoostTestTargets)
|
||||
include(DiscoverBoostTests)
|
||||
|
||||
set(types_test_SOURCES
|
||||
add_library(testdeps INTERFACE)
|
||||
|
||||
if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||
find_package(Boost QUIET COMPONENTS unit_test_framework)
|
||||
endif()
|
||||
|
||||
if(Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||
target_link_libraries(testdeps
|
||||
INTERFACE
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
)
|
||||
if(NOT Boost_USE_STATIC_LIBS)
|
||||
set(BOOST_TEST_DYN_LINK ON)
|
||||
endif()
|
||||
else()
|
||||
set(BOOST_TEST_USE_INCLUDED ON)
|
||||
endif()
|
||||
|
||||
target_link_libraries(testdeps
|
||||
INTERFACE
|
||||
${base_DEPS}
|
||||
)
|
||||
|
||||
configure_file(BoostTestConfig.h.in BoostTestTargetConfig.h @ONLY)
|
||||
|
||||
target_include_directories(testdeps
|
||||
INTERFACE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
target_sources(testdeps INTERFACE
|
||||
test-runner.cpp
|
||||
test-ctest.cpp
|
||||
)
|
||||
|
||||
Set(types_test_SOURCES
|
||||
icingaapplication-fixture.cpp
|
||||
base-type.cpp
|
||||
${base_OBJS}
|
||||
@ -44,16 +79,11 @@ endif()
|
||||
# but this results in boost signals e.g. in dbevents.cpp being triggered by icinga-checkresult.cpp test cases that
|
||||
# only pass partially initialised objects. Therefore, the types test cases are decoupled from base and moved to a
|
||||
# separate executable to not crash the base test cases.
|
||||
add_boost_test(types
|
||||
SOURCES test-runner.cpp ${types_test_SOURCES}
|
||||
LIBRARIES ${base_DEPS}
|
||||
TESTS
|
||||
types/gettype
|
||||
types/assign
|
||||
types/byname
|
||||
types/instantiate
|
||||
types/sort_by_load_after
|
||||
add_executable(testtypes
|
||||
${types_test_SOURCES}
|
||||
)
|
||||
target_link_libraries(testtypes testdeps)
|
||||
target_discover_boost_tests(testtypes)
|
||||
|
||||
set(base_test_SOURCES
|
||||
icingaapplication-fixture.cpp
|
||||
@ -103,251 +133,11 @@ if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(base test base_test_SOURCES)
|
||||
endif()
|
||||
|
||||
add_boost_test(base
|
||||
SOURCES test-runner.cpp ${base_test_SOURCES}
|
||||
LIBRARIES ${base_DEPS}
|
||||
TESTS
|
||||
base_array/construct
|
||||
base_array/getset
|
||||
base_array/resize
|
||||
base_array/insert
|
||||
base_array/remove
|
||||
base_array/unique
|
||||
base_array/foreach
|
||||
base_array/clone
|
||||
base_array/json
|
||||
base_base64/base64
|
||||
base_convert/tolong
|
||||
base_convert/todouble
|
||||
base_convert/tostring
|
||||
base_convert/tobool
|
||||
base_dictionary/construct
|
||||
base_dictionary/initializer1
|
||||
base_dictionary/initializer2
|
||||
base_dictionary/get1
|
||||
base_dictionary/get2
|
||||
base_dictionary/foreach
|
||||
base_dictionary/remove
|
||||
base_dictionary/clone
|
||||
base_dictionary/json
|
||||
base_dictionary/keys_ordered
|
||||
base_fifo/construct
|
||||
base_fifo/io
|
||||
base_io_engine/timeout_run
|
||||
base_io_engine/timeout_cancelled
|
||||
base_io_engine/timeout_scope
|
||||
base_io_engine/timeout_due_cancelled
|
||||
base_io_engine/timeout_due_scope
|
||||
base_json/encode
|
||||
base_json/decode
|
||||
base_json/invalid1
|
||||
base_object_packer/pack_null
|
||||
base_object_packer/pack_false
|
||||
base_object_packer/pack_true
|
||||
base_object_packer/pack_number
|
||||
base_object_packer/pack_string
|
||||
base_object_packer/pack_array
|
||||
base_object_packer/pack_object
|
||||
base_match/tolong
|
||||
base_netstring/netstring
|
||||
base_object/construct
|
||||
base_object/getself
|
||||
base_serialize/scalar
|
||||
base_serialize/array
|
||||
base_serialize/dictionary
|
||||
base_serialize/object
|
||||
base_shellescape/escape_basic
|
||||
base_shellescape/escape_quoted
|
||||
base_stacktrace/stacktrace
|
||||
base_stream/readline_stdio
|
||||
base_string/construct
|
||||
base_string/equal
|
||||
base_string/clear
|
||||
base_string/append
|
||||
base_string/trim
|
||||
base_string/contains
|
||||
base_string/replace
|
||||
base_string/index
|
||||
base_string/find
|
||||
base_string/vector_move
|
||||
base_string/move_string_out_of_Value_type
|
||||
base_timer/construct
|
||||
base_timer/interval
|
||||
base_timer/invoke
|
||||
base_timer/scope
|
||||
base_tlsutility/sha1
|
||||
base_tlsutility/iscauptodate_ok
|
||||
base_tlsutility/iscauptodate_expiring
|
||||
base_tlsutility/iscertuptodate_ok
|
||||
base_tlsutility/iscertuptodate_expiring
|
||||
base_tlsutility/iscertuptodate_old
|
||||
base_tlsutility/VerifyCertificate_revalidate
|
||||
base_utility/parse_version
|
||||
base_utility/compare_version
|
||||
base_utility/comparepasswords_works
|
||||
base_utility/comparepasswords_issafe
|
||||
base_utility/validateutf8
|
||||
base_utility/EscapeCreateProcessArg
|
||||
base_utility/TruncateUsingHash
|
||||
base_utility/FormatDateTime
|
||||
base_utility/NormalizeTm
|
||||
base_value/scalar
|
||||
base_value/convert
|
||||
base_value/format
|
||||
config_apply/gettargethosts_literal
|
||||
config_apply/gettargethosts_const
|
||||
config_apply/gettargethosts_swapped
|
||||
config_apply/gettargethosts_two
|
||||
config_apply/gettargethosts_three
|
||||
config_apply/gettargethosts_mixed
|
||||
config_apply/gettargethosts_redundant
|
||||
config_apply/gettargethosts_badconst
|
||||
config_apply/gettargethosts_notliteral
|
||||
config_apply/gettargethosts_wrongop
|
||||
config_apply/gettargethosts_wrongattr
|
||||
config_apply/gettargethosts_wrongvar
|
||||
config_apply/gettargethosts_noindexer
|
||||
config_apply/gettargetservices_literal
|
||||
config_apply/gettargetservices_const
|
||||
config_apply/gettargetservices_swapped_outer
|
||||
config_apply/gettargetservices_swapped_inner
|
||||
config_apply/gettargetservices_two
|
||||
config_apply/gettargetservices_three
|
||||
config_apply/gettargetservices_mixed
|
||||
config_apply/gettargetservices_redundant
|
||||
config_apply/gettargetservices_badconst
|
||||
config_apply/gettargetservices_notliteral
|
||||
config_apply/gettargetservices_wrongop_outer
|
||||
config_apply/gettargetservices_wrongop_host
|
||||
config_apply/gettargetservices_wrongop_service
|
||||
config_apply/gettargetservices_wrongattr_host
|
||||
config_apply/gettargetservices_wrongattr_service
|
||||
config_apply/gettargetservices_wrongvar_host
|
||||
config_apply/gettargetservices_wrongvar_service
|
||||
config_apply/gettargetservices_noindexer_host
|
||||
config_apply/gettargetservices_noindexer_service
|
||||
config_ops/simple
|
||||
config_ops/advanced
|
||||
icinga_checkresult/host_1attempt
|
||||
icinga_checkresult/host_2attempts
|
||||
icinga_checkresult/host_3attempts
|
||||
icinga_checkresult/service_1attempt
|
||||
icinga_checkresult/service_2attempts
|
||||
icinga_checkresult/service_3attempts
|
||||
icinga_checkresult/host_flapping_notification
|
||||
icinga_checkresult/service_flapping_notification
|
||||
icinga_checkresult/suppressed_notification
|
||||
icinga_dependencies/multi_parent
|
||||
icinga_dependencies/push_dependency_groups_to_registry
|
||||
icinga_dependencies/default_redundancy_group_registration_unregistration
|
||||
icinga_dependencies/simple_redundancy_group_registration_unregistration
|
||||
icinga_dependencies/mixed_redundancy_group_registration_unregsitration
|
||||
icinga_notification/strings
|
||||
icinga_notification/state_filter
|
||||
icinga_notification/type_filter
|
||||
icinga_notification/no_filter_problem_no_duplicate
|
||||
icinga_notification/filter_problem_no_duplicate
|
||||
icinga_notification/volatile_filter_problem_duplicate
|
||||
icinga_notification/no_recovery_filter_no_duplicate
|
||||
icinga_notification/recovery_filter_duplicate
|
||||
icinga_macros/simple
|
||||
icinga_legacytimeperiod/simple
|
||||
icinga_legacytimeperiod/is_in_range
|
||||
icinga_legacytimeperiod/out_of_range_segments
|
||||
icinga_legacytimeperiod/include_exclude_timeperiods
|
||||
icinga_legacytimeperiod/advanced
|
||||
icinga_legacytimeperiod/dst
|
||||
icinga_legacytimeperiod/dst_isinside
|
||||
icinga_legacytimeperiod/find_nth_weekday
|
||||
icinga_perfdata/empty
|
||||
icinga_perfdata/simple
|
||||
icinga_perfdata/quotes
|
||||
icinga_perfdata/multiple
|
||||
icinga_perfdata/multiline
|
||||
icinga_perfdata/normalize
|
||||
icinga_perfdata/uom
|
||||
icinga_perfdata/warncritminmax
|
||||
icinga_perfdata/ignore_warn_crit_ranges
|
||||
icinga_perfdata/invalid
|
||||
icinga_perfdata/multi
|
||||
icinga_perfdata/scientificnotation
|
||||
icinga_perfdata/parse_edgecases
|
||||
icinga_perfdata/empty_warn_crit_min_max
|
||||
methods_pluginnotificationtask/truncate_long_output
|
||||
remote_certs_fixture/prepare_directory
|
||||
remote_certs_fixture/cleanup_certs
|
||||
remote_httpmessage/request_parse
|
||||
remote_httpmessage/request_params
|
||||
remote_httpmessage/response_clear
|
||||
remote_httpmessage/response_flush_nothrow
|
||||
remote_httpmessage/response_flush_throw
|
||||
remote_httpmessage/response_write_empty
|
||||
remote_httpmessage/response_write_fixed
|
||||
remote_httpmessage/response_write_chunked
|
||||
remote_httpmessage/response_sendjsonbody
|
||||
remote_httpmessage/response_sendjsonerror
|
||||
remote_httpmessage/response_sendfile
|
||||
remote_httpserverconnection/expect_100_continue
|
||||
remote_httpserverconnection/bad_request
|
||||
remote_httpserverconnection/error_access_control
|
||||
remote_httpserverconnection/error_accept_header
|
||||
remote_httpserverconnection/authenticate_cn
|
||||
remote_httpserverconnection/authenticate_passwd
|
||||
remote_httpserverconnection/authenticate_error_wronguser
|
||||
remote_httpserverconnection/authenticate_error_wrongpasswd
|
||||
remote_httpserverconnection/reuse_connection
|
||||
remote_httpserverconnection/wg_abort
|
||||
remote_httpserverconnection/client_shutdown
|
||||
remote_httpserverconnection/handler_throw_error
|
||||
remote_httpserverconnection/handler_throw_streaming
|
||||
remote_httpserverconnection/liveness_disconnect
|
||||
remote_configpackageutility/ValidateName
|
||||
remote_url/id_and_path
|
||||
remote_url/parameters
|
||||
remote_url/get_and_set
|
||||
remote_url/format
|
||||
remote_url/illegal_legal_strings
|
||||
add_executable(testbase
|
||||
${base_test_SOURCES}
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
set_tests_properties(
|
||||
base-remote_httpmessage/request_parse
|
||||
base-remote_httpmessage/request_params
|
||||
base-remote_httpmessage/response_clear
|
||||
base-remote_httpmessage/response_flush_nothrow
|
||||
base-remote_httpmessage/response_flush_throw
|
||||
base-remote_httpmessage/response_write_empty
|
||||
base-remote_httpmessage/response_write_fixed
|
||||
base-remote_httpmessage/response_write_chunked
|
||||
base-remote_httpmessage/response_sendjsonbody
|
||||
base-remote_httpmessage/response_sendjsonerror
|
||||
base-remote_httpmessage/response_sendfile
|
||||
base-remote_httpserverconnection/expect_100_continue
|
||||
base-remote_httpserverconnection/bad_request
|
||||
base-remote_httpserverconnection/error_access_control
|
||||
base-remote_httpserverconnection/error_accept_header
|
||||
base-remote_httpserverconnection/authenticate_cn
|
||||
base-remote_httpserverconnection/authenticate_passwd
|
||||
base-remote_httpserverconnection/authenticate_error_wronguser
|
||||
base-remote_httpserverconnection/authenticate_error_wrongpasswd
|
||||
base-remote_httpserverconnection/reuse_connection
|
||||
base-remote_httpserverconnection/wg_abort
|
||||
base-remote_httpserverconnection/client_shutdown
|
||||
base-remote_httpserverconnection/handler_throw_error
|
||||
base-remote_httpserverconnection/handler_throw_streaming
|
||||
base-remote_httpserverconnection/liveness_disconnect
|
||||
PROPERTIES FIXTURES_REQUIRED ssl_certs)
|
||||
|
||||
set_tests_properties(
|
||||
base-remote_certs_fixture/prepare_directory
|
||||
PROPERTIES FIXTURES_SETUP ssl_certs
|
||||
)
|
||||
|
||||
set_tests_properties(
|
||||
base-remote_certs_fixture/cleanup_certs
|
||||
PROPERTIES FIXTURES_CLEANUP ssl_certs
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(testbase testdeps)
|
||||
target_discover_boost_tests(testbase)
|
||||
|
||||
if(ICINGA2_WITH_LIVESTATUS)
|
||||
set(livestatus_test_SOURCES
|
||||
@ -366,11 +156,12 @@ if(ICINGA2_WITH_LIVESTATUS)
|
||||
mkunity_target(livestatus test livestatus_test_SOURCES)
|
||||
endif()
|
||||
|
||||
add_boost_test(livestatus
|
||||
SOURCES test-runner.cpp ${livestatus_test_SOURCES}
|
||||
LIBRARIES ${base_DEPS}
|
||||
TESTS livestatus/hosts livestatus/services
|
||||
add_executable(testlivestatus
|
||||
${livestatus_test_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(testlivestatus testdeps)
|
||||
target_discover_boost_tests(testlivestatus)
|
||||
endif()
|
||||
|
||||
set(icinga_checkable_test_SOURCES
|
||||
@ -388,11 +179,8 @@ if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(icinga_checkable test icinga_checkable_test_SOURCES)
|
||||
endif()
|
||||
|
||||
add_boost_test(icinga_checkable
|
||||
SOURCES test-runner.cpp ${icinga_checkable_test_SOURCES}
|
||||
LIBRARIES ${base_DEPS}
|
||||
TESTS icinga_checkable_flapping/host_not_flapping
|
||||
icinga_checkable_flapping/host_flapping
|
||||
icinga_checkable_flapping/host_flapping_recover
|
||||
icinga_checkable_flapping/host_flapping_docs_example
|
||||
add_executable(icinga_checkable
|
||||
${icinga_checkable_test_SOURCES}
|
||||
)
|
||||
target_link_libraries(icinga_checkable testdeps)
|
||||
target_discover_boost_tests(icinga_checkable)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "remote-certificate-fixture.hpp"
|
||||
#include <BoostTestTargetConfig.h>
|
||||
#include "test/test-ctest.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -27,14 +27,14 @@ static void CleanupPersistentCertificateDir()
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(prepare_directory, ConfigurationDataDirFixture)
|
||||
BOOST_FIXTURE_TEST_CASE(prepare_directory, ConfigurationDataDirFixture, *CTestProperties("FIXTURES_SETUP ssl_certs"))
|
||||
{
|
||||
// Remove any existing left-overs of the persistent certificate directory from a previous
|
||||
// test run.
|
||||
CleanupPersistentCertificateDir();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(cleanup_certs, ConfigurationDataDirFixture)
|
||||
BOOST_FIXTURE_TEST_CASE(cleanup_certs, ConfigurationDataDirFixture, *CTestProperties("FIXTURES_CLEANUP ssl_certs"))
|
||||
{
|
||||
CleanupPersistentCertificateDir();
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <BoostTestTargetConfig.h>
|
||||
#include "remote/apilistener.hpp"
|
||||
#include "remote/pkiutility.hpp"
|
||||
#include "test/base-configuration-fixture.hpp"
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
namespace icinga {
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "remote/httpmessage.hpp"
|
||||
#include "remote/httputility.hpp"
|
||||
#include "test/base-tlsstream-fixture.hpp"
|
||||
#include "test/test-ctest.hpp"
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
|
||||
@ -29,7 +30,11 @@ static std::future<void> SpawnSynchronizedCoroutine(std::function<void(boost::as
|
||||
return future;
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(remote_httpmessage, TlsStreamFixture)
|
||||
// clang-format off
|
||||
BOOST_FIXTURE_TEST_SUITE(remote_httpmessage, TlsStreamFixture,
|
||||
*CTestProperties("FIXTURES_REQUIRED ssl_certs")
|
||||
*boost::unit_test::label("http"))
|
||||
// clang-format on
|
||||
|
||||
BOOST_AUTO_TEST_CASE(request_parse)
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "remote/httphandler.hpp"
|
||||
#include "test/base-testloggerfixture.hpp"
|
||||
#include "test/base-tlsstream-fixture.hpp"
|
||||
#include "test/test-ctest.hpp"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <utility>
|
||||
@ -93,7 +94,11 @@ private:
|
||||
|
||||
REGISTER_URLHANDLER("/v1/test", UnitTestHandler);
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(remote_httpserverconnection, HttpServerConnectionFixture)
|
||||
// clang-format off
|
||||
BOOST_FIXTURE_TEST_SUITE(remote_httpserverconnection, HttpServerConnectionFixture,
|
||||
*CTestProperties("FIXTURES_REQUIRED ssl_certs")
|
||||
*boost::unit_test::label("http"))
|
||||
// clang-format on
|
||||
|
||||
BOOST_AUTO_TEST_CASE(expect_100_continue)
|
||||
{
|
||||
|
126
test/test-ctest.cpp
Normal file
126
test/test-ctest.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "test-ctest.hpp"
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
BOOST_TEST_GLOBAL_FIXTURE(CTestFileGeneratorFixture);
|
||||
|
||||
boost::unit_test::decorator::base_ptr CTestProperties::clone() const
|
||||
{
|
||||
return boost::make_shared<CTestProperties>(m_Props);
|
||||
}
|
||||
|
||||
CTestFileGenerator::CTestFileGenerator(const boost::filesystem::path& testexe, const boost::filesystem::path& outfile)
|
||||
: m_Fp(outfile.string(), std::iostream::trunc), m_WorkDir(outfile.parent_path().string()),
|
||||
m_TestExe(testexe.string())
|
||||
{
|
||||
m_Fp.exceptions(std::iostream::badbit | std::iostream::failbit);
|
||||
}
|
||||
|
||||
void CTestFileGenerator::visit(const boost::unit_test::test_case& test)
|
||||
{
|
||||
m_Fp << "add_test(" << test.full_name() << " " << m_TestExe << " --run_test=" << test.full_name() << ")\n";
|
||||
m_Fp << "set_tests_properties(" << test.full_name() << "\n PROPERTIES"
|
||||
<< " WORKING_DIRECTORY " << m_WorkDir << "\n";
|
||||
|
||||
auto labels = test.p_labels.get();
|
||||
if (!labels.empty()) {
|
||||
m_Fp << " " << LabelsToProp(labels) << "\n";
|
||||
}
|
||||
|
||||
for (auto& props : m_PropsStack) {
|
||||
for (auto& prop : props) {
|
||||
m_Fp << " " << prop << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!test.is_enabled()) {
|
||||
m_Fp << " DISABLED\n";
|
||||
}
|
||||
|
||||
auto decs = test.p_decorators.get();
|
||||
for (auto& dec : decs) {
|
||||
auto ctp = boost::dynamic_pointer_cast<CTestProperties>(dec);
|
||||
if (ctp) {
|
||||
m_Fp << " " << ctp->m_Props << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
m_Fp << ")\n";
|
||||
m_Fp.flush();
|
||||
}
|
||||
|
||||
bool CTestFileGenerator::test_suite_start(const boost::unit_test::test_suite& suite)
|
||||
{
|
||||
m_PropsStack.emplace_back();
|
||||
|
||||
auto decs = suite.p_decorators.get();
|
||||
for (auto& dec : decs) {
|
||||
auto ctp = boost::dynamic_pointer_cast<CTestProperties>(dec);
|
||||
if (ctp) {
|
||||
m_PropsStack.back().push_back(ctp->m_Props);
|
||||
}
|
||||
}
|
||||
|
||||
auto labels = suite.p_labels.get();
|
||||
if (!labels.empty()) {
|
||||
m_PropsStack.back().push_back(LabelsToProp(labels));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTestFileGenerator::test_suite_finish(const boost::unit_test::test_suite&)
|
||||
{
|
||||
m_PropsStack.pop_back();
|
||||
}
|
||||
|
||||
std::string CTestFileGenerator::LabelsToProp(const std::vector<std::string>& labels)
|
||||
{
|
||||
std::string labelsProp{"LABELS \""};
|
||||
for (auto it = labels.begin(); it != labels.end(); ++it) {
|
||||
if (it != labels.begin()) {
|
||||
labelsProp.push_back(';');
|
||||
}
|
||||
|
||||
for (auto c : *it) {
|
||||
if (c == ';') {
|
||||
labelsProp.push_back('\\');
|
||||
}
|
||||
labelsProp.push_back(c);
|
||||
}
|
||||
}
|
||||
labelsProp.push_back('"');
|
||||
return labelsProp;
|
||||
}
|
||||
|
||||
CTestFileGeneratorFixture::CTestFileGeneratorFixture()
|
||||
{
|
||||
auto& mts = boost::unit_test::framework::master_test_suite();
|
||||
int argc = mts.argc;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string argument(mts.argv[i]);
|
||||
|
||||
if (argument == "--generate_ctest_config") {
|
||||
if (argc >= i + 1) {
|
||||
boost::filesystem::path testbin(mts.argv[0]);
|
||||
boost::filesystem::path file(mts.argv[i + 1]);
|
||||
|
||||
try {
|
||||
CTestFileGenerator visitor{testbin, file};
|
||||
traverse_test_tree(mts, visitor);
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Error: --generate_ctest_config failed with: " << ex.what() << '\n';
|
||||
std::_Exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Error: --generate_ctest_config specified with no argument.\n";
|
||||
std::_Exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::_Exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
57
test/test-ctest.hpp
Normal file
57
test/test-ctest.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <BoostTestTargetConfig.h>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/test/tree/traverse.hpp>
|
||||
#include <fstream>
|
||||
|
||||
namespace icinga {
|
||||
|
||||
/**
|
||||
* A boost test decorator to set additional ctest properties for the test.
|
||||
*/
|
||||
class CTestProperties : public boost::unit_test::decorator::base
|
||||
{
|
||||
public:
|
||||
explicit CTestProperties(std::string props) : m_Props(std::move(props)) {}
|
||||
|
||||
std::string m_Props;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Doesn't do anything to the case/suite it's applied to.
|
||||
*
|
||||
* However this gets added to the list so we can later find it by iterating the
|
||||
* decorators and dynamic_casting them to this type and get the m_props value.
|
||||
*/
|
||||
void apply(boost::unit_test::test_unit&) override {}
|
||||
[[nodiscard]] boost::unit_test::decorator::base_ptr clone() const override;
|
||||
};
|
||||
|
||||
class CTestFileGenerator : public boost::unit_test::test_tree_visitor
|
||||
{
|
||||
public:
|
||||
CTestFileGenerator(const boost::filesystem::path& testexe, const boost::filesystem::path& outfile);
|
||||
|
||||
void visit(const boost::unit_test::test_case& test) override;
|
||||
|
||||
bool test_suite_start(const boost::unit_test::test_suite& suite) override;
|
||||
void test_suite_finish(const boost::unit_test::test_suite& suite) override;
|
||||
|
||||
private:
|
||||
static std::string LabelsToProp(const std::vector<std::string>& labels);
|
||||
|
||||
std::ofstream m_Fp;
|
||||
boost::filesystem::path m_WorkDir;
|
||||
boost::filesystem::path m_TestExe;
|
||||
std::vector<std::vector<std::string>> m_PropsStack;
|
||||
};
|
||||
|
||||
struct CTestFileGeneratorFixture
|
||||
{
|
||||
CTestFileGeneratorFixture();
|
||||
};
|
||||
|
||||
} // namespace icinga
|
@ -4,9 +4,8 @@
|
||||
#define BOOST_TEST_NO_MAIN
|
||||
#define BOOST_TEST_ALTERNATIVE_INIT_API
|
||||
|
||||
#define TEST_INCLUDE_IMPLEMENTATION
|
||||
#include <BoostTestTargetConfig.h>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
int BOOST_TEST_CALL_DECL
|
||||
main(int argc, char **argv)
|
||||
|
262
third-party/cmake/BoostTestTargets.cmake
vendored
262
third-party/cmake/BoostTestTargets.cmake
vendored
@ -1,262 +0,0 @@
|
||||
# - Add tests using boost::test
|
||||
#
|
||||
# Add this line to your test files in place of including a basic boost test header:
|
||||
# #include <BoostTestTargetConfig.h>
|
||||
#
|
||||
# If you cannot do that and must use the included form for a given test,
|
||||
# include the line
|
||||
# // OVERRIDE_BOOST_TEST_INCLUDED_WARNING
|
||||
# in the same file with the boost test include.
|
||||
#
|
||||
# include(BoostTestTargets)
|
||||
# add_boost_test(<testdriver_name> SOURCES <source1> [<more sources...>]
|
||||
# [FAIL_REGULAR_EXPRESSION <additional fail regex>]
|
||||
# [LAUNCHER <generic launcher script>]
|
||||
# [LIBRARIES <library> [<library>...]]
|
||||
# [RESOURCES <resource> [<resource>...]]
|
||||
# [TESTS <testcasename> [<testcasename>...]]
|
||||
# [DEPENDENCIES <dependency> [<dependency>...]])
|
||||
#
|
||||
# If for some reason you need access to the executable target created,
|
||||
# it can be found in ${${testdriver_name}_TARGET_NAME} as specified when
|
||||
# you called add_boost_test
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Requires:
|
||||
# GetForceIncludeDefinitions
|
||||
# CopyResourcesToBuildTree
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__add_boost_test)
|
||||
return()
|
||||
endif()
|
||||
set(__add_boost_test YES)
|
||||
|
||||
set(BOOST_TEST_TARGET_PREFIX "boosttest")
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
find_package(Boost 1.34.0 QUIET)
|
||||
endif()
|
||||
|
||||
include(GetForceIncludeDefinitions)
|
||||
include(CopyResourcesToBuildTree)
|
||||
|
||||
if(Boost_FOUND)
|
||||
set(_boosttesttargets_libs)
|
||||
set(_boostConfig "BoostTestTargetsIncluded.h")
|
||||
if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||
find_package(Boost 1.34.0 QUIET COMPONENTS unit_test_framework)
|
||||
endif()
|
||||
if(Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||
set(_boosttesttargets_libs "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
||||
if(Boost_USE_STATIC_LIBS)
|
||||
set(_boostConfig "BoostTestTargetsStatic.h")
|
||||
else()
|
||||
set(_boostConfig "BoostTestTargetsDynamic.h")
|
||||
endif()
|
||||
endif()
|
||||
get_filename_component(_moddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
configure_file("${_moddir}/${_boostConfig}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/BoostTestTargetConfig.h"
|
||||
COPYONLY)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
function(add_boost_test _name)
|
||||
if(NOT BUILD_TESTING)
|
||||
return()
|
||||
endif()
|
||||
if("${CMAKE_VERSION}" VERSION_LESS "2.8.0")
|
||||
if(NOT "${_boost_test_cmakever_pestered}x" EQUAL "${CMAKE_VERSION}x")
|
||||
message(STATUS
|
||||
"Not adding boost::test targets - CMake 2.8.0 or newer required, using ${CMAKE_VERSION}")
|
||||
set(_boost_test_cmakever_pestered
|
||||
"${CMAKE_VERSION}"
|
||||
CACHE
|
||||
INTERNAL
|
||||
""
|
||||
FORCE)
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
# parse arguments
|
||||
set(_nowhere)
|
||||
set(_curdest _nowhere)
|
||||
set(_val_args
|
||||
SOURCES
|
||||
FAIL_REGULAR_EXPRESSION
|
||||
LAUNCHER
|
||||
LIBRARIES
|
||||
RESOURCES
|
||||
TESTS
|
||||
DEPENDENCIES)
|
||||
set(_bool_args
|
||||
USE_COMPILED_LIBRARY)
|
||||
foreach(_arg ${_val_args} ${_bool_args})
|
||||
set(${_arg})
|
||||
endforeach()
|
||||
foreach(_element ${ARGN})
|
||||
list(FIND _val_args "${_element}" _val_arg_find)
|
||||
list(FIND _bool_args "${_element}" _bool_arg_find)
|
||||
if("${_val_arg_find}" GREATER "-1")
|
||||
set(_curdest "${_element}")
|
||||
elseif("${_bool_arg_find}" GREATER "-1")
|
||||
set("${_element}" ON)
|
||||
set(_curdest _nowhere)
|
||||
else()
|
||||
list(APPEND ${_curdest} "${_element}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_nowhere)
|
||||
message(FATAL_ERROR "Syntax error in use of add_boost_test!")
|
||||
endif()
|
||||
|
||||
if(NOT SOURCES)
|
||||
message(FATAL_ERROR
|
||||
"Syntax error in use of add_boost_test: at least one source file required!")
|
||||
endif()
|
||||
|
||||
if(Boost_FOUND)
|
||||
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
|
||||
set(includeType)
|
||||
foreach(src ${SOURCES})
|
||||
file(READ ${src} thefile)
|
||||
if("${thefile}" MATCHES ".*BoostTestTargetConfig.h.*")
|
||||
set(includeType CONFIGURED)
|
||||
set(includeFileLoc ${src})
|
||||
break()
|
||||
elseif("${thefile}" MATCHES ".*boost/test/included/unit_test.hpp.*")
|
||||
set(includeType INCLUDED)
|
||||
set(includeFileLoc ${src})
|
||||
set(_boosttesttargets_libs) # clear this out - linking would be a bad idea
|
||||
if(NOT
|
||||
"${thefile}"
|
||||
MATCHES
|
||||
".*OVERRIDE_BOOST_TEST_INCLUDED_WARNING.*")
|
||||
message("Please replace the include line in ${src} with this alternate include line instead:")
|
||||
message(" \#include <BoostTestTargetConfig.h>")
|
||||
message("Once you've saved your changes, re-run CMake. (See BoostTestTargets.cmake for more info)")
|
||||
endif()
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT _boostTestTargetsNagged${_name} STREQUAL "${includeType}")
|
||||
if("${includeType}" STREQUAL "CONFIGURED")
|
||||
message(STATUS
|
||||
"Test '${_name}' uses the CMake-configurable form of the boost test framework - congrats! (Including File: ${includeFileLoc})")
|
||||
elseif("${includeType}" STREQUAL "INCLUDED")
|
||||
message("In test '${_name}': ${includeFileLoc} uses the 'included' form of the boost unit test framework.")
|
||||
else()
|
||||
message("In test '${_name}': Didn't detect the CMake-configurable boost test include.")
|
||||
message("Please replace your existing boost test include in that test with the following:")
|
||||
message(" \#include <BoostTestTargetConfig.h>")
|
||||
message("Once you've saved your changes, re-run CMake. (See BoostTestTargets.cmake for more info)")
|
||||
endif()
|
||||
endif()
|
||||
set(_boostTestTargetsNagged${_name}
|
||||
"${includeType}"
|
||||
CACHE
|
||||
INTERNAL
|
||||
""
|
||||
FORCE)
|
||||
|
||||
|
||||
if(RESOURCES)
|
||||
list(APPEND SOURCES ${RESOURCES})
|
||||
endif()
|
||||
|
||||
# Generate a unique target name, using the relative binary dir
|
||||
# and provided name. (transform all / into _ and remove all other
|
||||
# non-alphabet characters)
|
||||
file(RELATIVE_PATH
|
||||
targetpath
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||
string(REGEX REPLACE "[^A-Za-z/_]" "" targetpath "${targetpath}")
|
||||
string(REPLACE "/" "_" targetpath "${targetpath}")
|
||||
|
||||
set(_target_name ${BOOST_TEST_TARGET_PREFIX}-${targetpath}-${_name})
|
||||
set(${_name}_TARGET_NAME "${_target_name}" PARENT_SCOPE)
|
||||
|
||||
# Build the test.
|
||||
add_executable(${_target_name} ${SOURCES})
|
||||
|
||||
list(APPEND LIBRARIES ${_boosttesttargets_libs})
|
||||
|
||||
if(LIBRARIES)
|
||||
target_link_libraries(${_target_name} ${LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(RESOURCES)
|
||||
set_property(TARGET ${_target_name} PROPERTY RESOURCE ${RESOURCES})
|
||||
copy_resources_to_build_tree(${_target_name})
|
||||
endif()
|
||||
|
||||
if(NOT Boost_TEST_FLAGS)
|
||||
# set(Boost_TEST_FLAGS --catch_system_error=yes --output_format=XML)
|
||||
set(Boost_TEST_FLAGS --catch_system_error=yes)
|
||||
endif()
|
||||
|
||||
# TODO: Figure out why only recent boost handles individual test running properly
|
||||
|
||||
if(LAUNCHER)
|
||||
set(_test_command ${LAUNCHER} "\$<TARGET_FILE:${_target_name}>")
|
||||
else()
|
||||
set(_test_command ${_target_name})
|
||||
endif()
|
||||
|
||||
if(TESTS)
|
||||
foreach(_test ${TESTS})
|
||||
add_test(NAME
|
||||
${_name}-${_test}
|
||||
COMMAND
|
||||
${_test_command}
|
||||
--run_test=${_test}
|
||||
${Boost_TEST_FLAGS})
|
||||
if(FAIL_REGULAR_EXPRESSION)
|
||||
set_tests_properties(${_name}-${_test}
|
||||
PROPERTIES
|
||||
FAIL_REGULAR_EXPRESSION
|
||||
"${FAIL_REGULAR_EXPRESSION}")
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
add_test(NAME
|
||||
${_name}-boost_test
|
||||
COMMAND
|
||||
${_test_command}
|
||||
${Boost_TEST_FLAGS})
|
||||
if(FAIL_REGULAR_EXPRESSION)
|
||||
set_tests_properties(${_name}-${_test}
|
||||
PROPERTIES
|
||||
FAIL_REGULAR_EXPRESSION
|
||||
"${FAIL_REGULAR_EXPRESSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (DEPENDENCIES)
|
||||
add_dependencies(${_target_name} ${DEPENDENCIES})
|
||||
endif()
|
||||
|
||||
# CppCheck the test if we can.
|
||||
if(COMMAND add_cppcheck)
|
||||
add_cppcheck(${_target_name} STYLE UNUSED_FUNCTIONS)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endfunction()
|
9
third-party/cmake/BoostTestTargetsDynamic.h
vendored
9
third-party/cmake/BoostTestTargetsDynamic.h
vendored
@ -1,9 +0,0 @@
|
||||
// Small header computed by CMake to set up boost test.
|
||||
// include AFTER #define BOOST_TEST_MODULE whatever
|
||||
// but before any other boost test includes.
|
||||
|
||||
// Using the Boost UTF dynamic library
|
||||
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
7
third-party/cmake/BoostTestTargetsIncluded.h
vendored
7
third-party/cmake/BoostTestTargetsIncluded.h
vendored
@ -1,7 +0,0 @@
|
||||
// Small header computed by CMake to set up boost test.
|
||||
// include AFTER #define BOOST_TEST_MODULE whatever
|
||||
// but before any other boost test includes.
|
||||
|
||||
// Using the Boost UTF included framework
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
7
third-party/cmake/BoostTestTargetsStatic.h
vendored
7
third-party/cmake/BoostTestTargetsStatic.h
vendored
@ -1,7 +0,0 @@
|
||||
// Small header computed by CMake to set up boost test.
|
||||
// include AFTER #define BOOST_TEST_MODULE whatever
|
||||
// but before any other boost test includes.
|
||||
|
||||
// Using the Boost UTF static library
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
83
third-party/cmake/CopyResourcesToBuildTree.cmake
vendored
83
third-party/cmake/CopyResourcesToBuildTree.cmake
vendored
@ -1,83 +0,0 @@
|
||||
# - Copy the resources your app needs to the build tree.
|
||||
#
|
||||
# copy_resources_to_build_tree(<target_name>)
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__copy_resources_to_build_tree)
|
||||
return()
|
||||
endif()
|
||||
set(__copy_resources_to_build_tree YES)
|
||||
|
||||
function(copy_resources_to_build_tree _target)
|
||||
get_target_property(_resources ${_target} RESOURCE)
|
||||
if(NOT _resources)
|
||||
# Bail if no resources
|
||||
message(STATUS
|
||||
"Told to copy resources for target ${_target}, but "
|
||||
"no resources are set!")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_target_property(_path ${_target} LOCATION)
|
||||
get_filename_component(_path "${_path}" PATH)
|
||||
|
||||
if(NOT MSVC AND NOT "${CMAKE_GENERATOR}" MATCHES "Makefiles")
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
get_target_property(_path${_config} ${_target} LOCATION_${_config})
|
||||
get_filename_component(_path${_config} "${_path${_config}}" PATH)
|
||||
add_custom_command(TARGET ${_target}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
ARGS -E make_directory "${_path${_config}}/"
|
||||
COMMENT "Creating directory ${_path${_config}}/")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
foreach(_res ${_resources})
|
||||
if(NOT IS_ABSOLUTE "${_res}")
|
||||
get_filename_component(_res "${_res}" ABSOLUTE)
|
||||
endif()
|
||||
get_filename_component(_name "${_res}" NAME)
|
||||
|
||||
if(MSVC)
|
||||
# Working dir is solution file dir, not exe file dir.
|
||||
add_custom_command(TARGET ${_target}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
ARGS -E copy "${_res}" "${CMAKE_BINARY_DIR}/"
|
||||
COMMENT "Copying ${_name} to ${CMAKE_BINARY_DIR}/ for MSVC")
|
||||
else()
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Makefiles")
|
||||
add_custom_command(TARGET ${_target}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
ARGS -E copy "${_res}" "${_path}/"
|
||||
COMMENT "Copying ${_name} to ${_path}/")
|
||||
else()
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
add_custom_command(TARGET ${_target}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
ARGS -E copy "${_res}" "${_path${_config}}"
|
||||
COMMENT "Copying ${_name} to ${_path${_config}}")
|
||||
endforeach()
|
||||
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
@ -1,44 +0,0 @@
|
||||
# - Get the platform-appropriate flags to add to force inclusion of a file
|
||||
#
|
||||
# The most common use of this is to use a generated config.h-type file
|
||||
# placed out of the source tree in all files.
|
||||
#
|
||||
# get_force_include_definitions(var forcedincludefiles...) -
|
||||
# where var is the name of your desired output variable, and everything
|
||||
# else is a source file to forcibly include.
|
||||
# a list item to be filtered.
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__get_force_include_definitions)
|
||||
return()
|
||||
endif()
|
||||
set(__get_force_include_definitions YES)
|
||||
|
||||
function(get_force_include_definitions var)
|
||||
set(_flagprefix)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(_flag "-include")
|
||||
elseif(MSVC)
|
||||
set(_flag "/FI")
|
||||
else()
|
||||
message(SEND_ERROR "You don't seem to be using MSVC or GCC, but")
|
||||
message(SEND_ERROR "the project called get_force_include_definitions.")
|
||||
message(SEND_ERROR "Contact this project with the name of your")
|
||||
message(FATAL_ERROR "compiler and preferably the flag to force includes")
|
||||
endif()
|
||||
|
||||
set(_out)
|
||||
foreach(_item ${ARGN})
|
||||
list(APPEND _out "${_flag} \"${_item}\"")
|
||||
endforeach()
|
||||
set(${var} "${_out}" PARENT_SCOPE)
|
||||
endfunction()
|
Loading…
x
Reference in New Issue
Block a user