[CMAKE] Get rid of the set_cpp macro

Instead of messing with global variables and the like, we introduce two target properties:
 - WITH_CXX_EXCEPTIONS: if you want to use C++ exceptions
 - WITH_CXX_RTTI: if you need RTTI in your module
You can use the newly introduced set_target_cpp_properties function, with WITH_EXCEPTIONS and WITH_RTTI arguments
We also introduce two libraries :
 - cpprt: for C++ runtime routines
 - cppstl: for the C++ standard template library

NB: On GCC, this requires to create imported libraries with the related built-in libraries:libsupc++, limingwex, libstdc++

Finally, we manage the relevant flags with the ad-hoc generator expressions

So, if you don't need exceptions, nor RTTI, nor use any runtime at all: you simply have nothing else to do than add your C++ file to your module
This commit is contained in:
Jérôme Gardou 2020-09-18 09:34:18 +02:00 committed by Jérôme Gardou
parent 980ce77316
commit d6ea8659c8
69 changed files with 193 additions and 259 deletions

View file

@ -1,86 +1,4 @@
# set_cpp
# Marks the current folder as containing C++ modules, additionally enabling
# specific C++ language features as specified (all of these default to off):
#
# WITH_RUNTIME
# Links with the C++ runtime. Enable this for modules which use new/delete or
# RTTI, but do not require STL. This is the right choice if you see undefined
# references to operator new/delete, vector constructor/destructor iterator,
# type_info::vtable, ...
# Note: this only affects linking, so cannot be used for static libraries.
# WITH_RTTI
# Enables run-time type information. Enable this if the module uses typeid or
# dynamic_cast. You will probably need to enable WITH_RUNTIME as well, if
# you're not already using STL.
# WITH_EXCEPTIONS
# Enables C++ exception handling. Enable this if the module uses try/catch or
# throw. You might also need this if you use a standard operator new (the one
# without nothrow).
# WITH_STL
# Enables standard C++ headers and links to the Standard Template Library.
# Use this for modules using anything from the std:: namespace, e.g. maps,
# strings, vectors, etc.
# Note: this affects both compiling (via include directories) and
# linking (by adding STL). Implies WITH_RUNTIME.
# FIXME: WITH_STL is currently also required for runtime headers such as
# <new> and <exception>. This is not a big issue because in stl-less
# environments you usually don't want those anyway; but we might want
# to have modules like this in the future.
#
# Examples:
# set_cpp()
# Enables the C++ language, but will cause errors if any runtime or standard
# library features are used. This should be the default for C++ in kernel
# mode or otherwise restricted environments.
# Note: this is required to get libgcc (for multiplication/division) linked
# in for C++ modules, and to set the correct language for precompiled
# header files, so it IS required even with no features specified.
# set_cpp(WITH_RUNTIME)
# Links with the C++ runtime, so that e.g. custom operator new implementations
# can be used in a restricted environment. This is also required for linking
# with libraries (such as ATL) which have RTTI enabled, even if the module in
# question does not use WITH_RTTI.
# set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL)
# The full package. This will adjust compiler and linker so that all C++
# features can be used.
macro(set_cpp)
cmake_parse_arguments(__cppopts "WITH_RUNTIME;WITH_RTTI;WITH_EXCEPTIONS;WITH_STL" "" "" ${ARGN})
if(__cppopts_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "set_cpp: unparsed arguments ${__cppopts_UNPARSED_ARGUMENTS}")
endif()
if(__cppopts_WITH_RUNTIME)
set(CPP_USE_RT 1)
endif()
if(__cppopts_WITH_RTTI)
if(MSVC)
replace_compile_flags("/GR-" "/GR")
else()
replace_compile_flags_language("-fno-rtti" "-frtti" "CXX")
endif()
endif()
if(__cppopts_WITH_EXCEPTIONS)
if(MSVC)
replace_compile_flags("/EHs-c-" "/EHsc")
else()
replace_compile_flags_language("-fno-exceptions" "-fexceptions" "CXX")
endif()
endif()
if(__cppopts_WITH_STL)
set(CPP_USE_STL 1)
if(MSVC)
add_definitions(-DNATIVE_CPP_INCLUDE=${REACTOS_SOURCE_DIR}/sdk/include/c++)
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/c++/stlport)
else()
replace_compile_flags("-nostdinc" " ")
add_definitions(-DPAL_STDCPP_COMPAT)
endif()
endif()
set(IS_CPP 1)
endmacro()
function(add_dependency_node _node)
if(GENERATE_DEPENDENCY_GRAPH)
get_target_property(_type ${_node} TYPE)
@ -988,3 +906,15 @@ else()
macro(add_pch _target _pch _skip_list)
endmacro()
endif()
function(set_target_cpp_properties _target)
cmake_parse_arguments(_CPP "WITH_EXCEPTIONS;WITH_RTTI" "" "" ${ARGN})
if (_CPP_WITH_EXCEPTIONS)
set_target_properties(${_target} PROPERTIES WITH_CXX_EXCEPTIONS TRUE)
endif()
if (_CPP_WITH_RTTI)
set_target_properties(${_target} PROPERTIES WITH_CXX_RTTI TRUE)
endif()
endfunction()

View file

@ -41,8 +41,9 @@ endif()
# Compiler Core
add_compile_flags("-pipe -fms-extensions -fno-strict-aliasing")
# Prevent GCC from searching any of the default directories
add_compile_flags("-nostdinc")
# Prevent GCC from searching any of the default directories.
# The case for C++ is handled through the reactos_c++ INTERFACE library
add_compile_options("$<$<NOT:$<COMPILE_LANGUAGE:CXX>>:-nostdinc>")
add_compile_flags("-mstackrealign")
add_compile_flags("-fno-aggressive-loop-optimizations")
@ -68,8 +69,6 @@ if(DBG)
endif()
endif()
add_compile_flags_language("-fno-rtti -fno-exceptions" "CXX")
#bug
#file(TO_NATIVE_PATH ${REACTOS_SOURCE_DIR} REACTOS_SOURCE_DIR_NATIVE)
#workaround
@ -292,17 +291,6 @@ function(set_image_base MODULE IMAGE_BASE)
endfunction()
function(set_module_type_toolchain MODULE TYPE)
if(CPP_USE_STL)
if((${TYPE} STREQUAL "kernelmodedriver") OR (${TYPE} STREQUAL "wdmdriver"))
message(FATAL_ERROR "Use of STL in kernelmodedriver or wdmdriver type module prohibited")
endif()
target_link_libraries(${MODULE} -lstdc++ -lsupc++ -lgcc -lmingwex)
elseif(CPP_USE_RT)
target_link_libraries(${MODULE} -lsupc++ -lgcc)
elseif(IS_CPP)
target_link_libraries(${MODULE} -lgcc)
endif()
if((${TYPE} STREQUAL "kernelmodedriver") OR (${TYPE} STREQUAL "wdmdriver"))
add_target_link_flags(${MODULE} "-Wl,--exclude-all-symbols,-file-alignment=0x1000,-section-alignment=0x1000")
if(${TYPE} STREQUAL "wdmdriver")
@ -440,3 +428,47 @@ function(add_linker_script _target _linker_script_file)
add_target_link_flags(${_target} "-Wl,-T,${_file_full_path}")
add_target_property(${_target} LINK_DEPENDS ${_file_full_path})
endfunction()
# Manage our C++ options
# we disable standard includes if we don't use the STL
add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<NOT:$<IN_LIST:cppstl,$<TARGET_PROPERTY:LINK_LIBRARIES>>>>:-nostdinc>")
# we disable RTTI, unless said so
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_RTTI>>,-frtti,-fno-rtti>>")
# We disable exceptions, unless said so
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_EXCEPTIONS>>,-fexceptions,-fno-exceptions>>")
# Find default G++ libraries
add_library(libgcc STATIC IMPORTED)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libgcc.a OUTPUT_VARIABLE LIBGCC_LOCATION)
string(STRIP ${LIBGCC_LOCATION} LIBGCC_LOCATION)
set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${LIBGCC_LOCATION})
# libgcc needs kernel32 imports, a CRT and msvcrtex
target_link_libraries(libgcc INTERFACE libkernel32 libmsvcrt msvcrtex)
add_library(libsupc++ STATIC IMPORTED GLOBAL)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libsupc++.a OUTPUT_VARIABLE LIBSUPCXX_LOCATION)
string(STRIP ${LIBSUPCXX_LOCATION} LIBSUPCXX_LOCATION)
set_target_properties(libsupc++ PROPERTIES IMPORTED_LOCATION ${LIBSUPCXX_LOCATION})
# libsupc++ requires libgcc
target_link_libraries(libsupc++ INTERFACE libgcc)
add_library(libmingwex STATIC IMPORTED)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libmingwex.a OUTPUT_VARIABLE LIBMINGWEX_LOCATION)
string(STRIP ${LIBMINGWEX_LOCATION} LIBMINGWEX_LOCATION)
set_target_properties(libmingwex PROPERTIES IMPORTED_LOCATION ${LIBMINGWEX_LOCATION})
# libmingwex requires a CRT and imports from kernel32
target_link_libraries(libmingwex INTERFACE libmsvcrt libkernel32)
add_library(libstdc++ STATIC IMPORTED GLOBAL)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libstdc++.a OUTPUT_VARIABLE LIBSTDCCXX_LOCATION)
string(STRIP ${LIBSTDCCXX_LOCATION} LIBSTDCCXX_LOCATION)
set_target_properties(libstdc++ PROPERTIES IMPORTED_LOCATION ${LIBSTDCCXX_LOCATION})
# libstdc++ requires libsupc++ and mingwex provided by GCC
target_link_libraries(libstdc++ INTERFACE libsupc++ libmingwex)
# this is for our SAL annotations
target_compile_definitions(libstdc++ INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:PAL_STDCPP_COMPAT>")
# Create our alias libraries
add_library(cppstl ALIAS libstdc++)
add_library(cpprt ALIAS libsupc++)

View file

@ -42,7 +42,7 @@ endif()
# Disable RTTI, exception handling and buffer security checks by default.
# These require run-time support that may not always be available.
add_compile_flags("/GR- /EHs-c- /GS-")
add_compile_flags("/GS-")
if(USE_CLANG_CL)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "Note: including file: ")
@ -252,14 +252,6 @@ function(set_image_base MODULE IMAGE_BASE)
endfunction()
function(set_module_type_toolchain MODULE TYPE)
if(CPP_USE_STL)
if((${TYPE} STREQUAL "kernelmodedriver") OR (${TYPE} STREQUAL "wdmdriver"))
message(FATAL_ERROR "Use of STL in kernelmodedriver or wdmdriver type module prohibited")
endif()
target_link_libraries(${MODULE} cpprt stlport oldnames)
elseif(CPP_USE_RT)
target_link_libraries(${MODULE} cpprt)
endif()
if((${TYPE} STREQUAL "win32dll") OR (${TYPE} STREQUAL "win32ocx") OR (${TYPE} STREQUAL "cpl"))
add_target_link_flags(${MODULE} "/DLL")
elseif(${TYPE} STREQUAL "kernelmodedriver")
@ -559,3 +551,17 @@ function(add_linker_script _target _linker_script_file)
add_target_property(${_target} LINK_DEPENDS ${_file_full_path})
endif()
endfunction()
# handle C++ options
# disable RTTI unless said so
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_RTTI>>,/GR,/GR->>")
# disable exceptions unless said so
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_EXCEPTIONS>>,/EHsc,/EHs-c->>")
# Create our interface libraries wrapping the needed library for this compiler
add_library(cppstl INTERFACE)
target_link_libraries(cppstl INTERFACE cpprt stlport oldnames)
# We set this properties through our INTERFACE library
set_target_properties(cppstl PROPERTIES INTERFACE_WITH_CXX_STL TRUE)
# add_library(cpprt INTERFACE)
# Our runtime library is already called cpprt

View file

@ -1,5 +1,4 @@
set_cpp()
list(APPEND SOURCE
cardbitmaps.cpp
@ -15,7 +14,9 @@ list(APPEND SOURCE
dropzone.cpp
cardlib.h)
add_library(cardlib ${SOURCE})
add_library(cardlib STATIC ${SOURCE})
target_link_libraries(cardlib PRIVATE cpprt)
target_include_directories(cardlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT MSVC)
target_compile_options(cardlib PRIVATE "-Wno-unused-but-set-variable")

View file

@ -2,13 +2,6 @@
#uncomment this if you want to test c++ compilation
#add_subdirectory(test)
set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL)
add_definitions(
-D_STLP_USE_EXCEPTIONS
-D_DLL -D__USE_CRTIMP
-D_BUILD_STLPORT)
list(APPEND SOURCE
src/allocators.cpp
src/bitset.cpp
@ -53,5 +46,14 @@ if(USE_CLANG_CL)
target_compile_options(stlport PRIVATE -Wno-tautological-unsigned-zero-compare)
endif()
target_include_directories(stlport PRIVATE ${REACTOS_SOURCE_DIR}/sdk/include/c++/stlport)
target_compile_definitions(stlport PRIVATE
_STLP_USE_EXCEPTIONS _DLL __USE_CRTIMP
_BUILD_STLPORT NATIVE_CPP_INCLUDE=${REACTOS_SOURCE_DIR}/sdk/include/c++)
target_include_directories(stlport INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:${REACTOS_SOURCE_DIR}/sdk/include/c++/stlport>")
target_compile_definitions(stlport INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:NATIVE_CPP_INCLUDE=${REACTOS_SOURCE_DIR}/sdk/include/c++>")
set_target_cpp_properties(stlport WITH_EXCEPTIONS WITH_RTTI)
add_dependencies(stlport xdk)
add_pch(stlport src/stlport_prefix.h SOURCE)

View file

@ -1,4 +1,6 @@
set_cpp(WITH_EXCEPTIONS WITH_STL)
add_library(comsupp comsupp.cpp)
target_link_libraries(comsupp PRIVATE cppstl)
set_target_cpp_properties(comsupp WITH_EXCEPTIONS)
add_dependencies(comsupp psdk)

View file

@ -1,6 +1,4 @@
set_cpp(WITH_EXCEPTIONS)
include_directories(
${REACTOS_SOURCE_DIR}/sdk/lib/crt/include
${REACTOS_SOURCE_DIR}/sdk/include/c++)
@ -21,4 +19,5 @@ elseif(ARCH STREQUAL "arm")
endif()
add_library(cpprt ${SOURCE} ${cpprt_asm})
set_target_cpp_properties(cpprt WITH_EXCEPTIONS)
add_dependencies(cpprt xdk)

View file

@ -1,4 +1,3 @@
set_cpp()
add_library(stdunk cunknown.cpp)
add_dependencies(stdunk xdk)