Skip to content

Commit

Permalink
Merge pull request #1373 from ethouris/dev-fix-compiler-standard-old
Browse files Browse the repository at this point in the history
Fixed C++ standard with old cmake and syntax specification
  • Loading branch information
maxsharabayko authored Jun 25, 2020
2 parents c2bc705 + ef2f129 commit 10ed37b
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 48 deletions.
155 changes: 107 additions & 48 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -367,66 +367,115 @@ else()
set (ENABLE_CXX11 1)
endif()

function (srt_check_cxxstd stdval OUT_STD OUT_PFX)

set (STDPFX c++)
if (stdval MATCHES "([^+]+\\++)([0-9]*)")
set (STDPFX ${CMAKE_MATCH_1})
set (STDCXX ${CMAKE_MATCH_2})
elseif (stdval MATCHES "[0-9]*")
set (STDCXX ${stdval})
else()
set (STDCXX 0)
endif()

# Handle C++98 < C++11
# Please fix this around 2070 year.
if (${STDCXX} GREATER 80)
set (STDCXX 03)
endif()

# return
set (${OUT_STD} ${STDCXX} PARENT_SCOPE)
set (${OUT_PFX} ${STDPFX} PARENT_SCOPE)
endfunction()

if (NOT ENABLE_CXX11)
message(WARNING "Parts that require C++11 support will be disabled (srt-live-transmit)")
if (ENABLE_STDCXX_SYNC)
message(ERROR "ENABLE_STDCXX_SYNC is set, but C++11 is disabled by ENABLE_CXX11")
message(FATAL_ERROR "ENABLE_STDCXX_SYNC is set, but C++11 is disabled by ENABLE_CXX11")
endif()
if (DEFINED USE_CXX_STD)
message(ERROR "USE_CXX_STD can be set only when ENABLE_CXX11 is on")
message(FATAL_ERROR "USE_CXX_STD can be set only when ENABLE_CXX11 is on")
endif()
elseif (ENABLE_STDCXX_SYNC)
add_definitions(-DENABLE_STDCXX_SYNC=1)
set(CMAKE_CXX_STANDARD 11)
if (DEFINED USE_CXX_STD)
srt_check_cxxstd(${USE_CXX_STD} STDCXX STDPFX)
# If defined, make sure it's at least C++11
if (${STDCXX} LESS 11)
message(FATAL_ERROR "If ENABLE_STDCXX_SYNC, then USE_CXX_STD must specify at least C++11")
endif()
else()
set (USE_CXX_STD 11)
endif()
endif()

message(STATUS "STDCXX_SYNC: ${ENABLE_STDCXX_SYNC}")

if (CMAKE_MAJOR_VERSION LESS 3)
set (FORCE_CXX_STANDARD_GNUONLY 1)
endif()

if (DEFINED USE_CXX_STD)
string(SUBSTRING "${USE_CXX_STD}" 0 3 STDPFX)
if (${STDPFX} GREATER 0)
set (STDCXX ${USE_CXX_STD})
set (USE_CXX_STD "c++${STDCXX}")
else()
string(SUBSTRING "${USE_CXX_STD}" 3 2 STDCXX)
srt_check_cxxstd(${USE_CXX_STD} STDCXX STDPFX)

if (${STDCXX} EQUAL 0)
message(FATAL_ERROR "USE_CXX_STD: Must specify 03/11/14/17/20 possibly with c++/gnu++ prefix")
endif()

if (NOT STDCXX STREQUAL "")

# Handle C++98 < C++11
# Please fix this around 2070 year.
if (${STDCXX} GREATER 80)
set (STDCXX 03)
endif()
if (${STDCXX} LESS 11)
if (ENABLE_STDCXX_SYNC)
message(ERROR "If ENABLE_STDCXX_SYNC, then you can't USE_CXX_STD less than 11")
if (${STDCXX} LESS 11)
if (ENABLE_STDCXX_SYNC)
message(FATAL_ERROR "If ENABLE_STDCXX_SYNC, then you can't USE_CXX_STD less than 11")
endif()
# Set back to 98 because cmake doesn't understand 03.
set (STDCXX 98)
# This enforces C++03 standard on SRT.
# Apps still use C++11

# Set this through independent flags
set (USE_CXX_STD_LIB ${STDCXX})
set (USE_CXX_STD_APP "")
set (FORCE_CXX_STANDARD 1)
message(STATUS "C++ STANDARD: library: C++${STDCXX}, but apps still at least C++11")
elseif (FORCE_CXX_STANDARD_GNUONLY)
# CMake is too old to handle CMAKE_CXX_STANDARD,
# use bare GNU options.
set (FORCE_CXX_STANDARD 1)
set (USE_CXX_STD_APP ${STDCXX})
set (USE_CXX_STD_LIB ${STDCXX})
message(STATUS "C++ STANDARD: using C++${STDCXX} for all - GNU only")
else()
# This enforces this standard on both apps and library,
# so set this as global C++ standard option
set (CMAKE_CXX_STANDARD ${STDCXX})
unset (FORCE_CXX_STANDARD)

# Do not set variables to not duplicate flags
set (USE_CXX_STD_LIB "")
set (USE_CXX_STD_APP "")
message(STATUS "C++ STANDARD: using C++${STDCXX} for all")
endif()
# This enforces C++03 standard on SRT.
# Apps still use C++11

# Set this through independent flags
set (USE_CXX_STD_LIB ${STDCXX})
set (USE_CXX_STD_APP "")
else()
# This enforces this standard on both apps and library,
# so set this as global C++ standard option
set (CMAKE_CXX_STANDARD ${STDCXX})
unset (FORCE_CXX_STANDARD)

# Do not set variables to not duplicate flags
set (USE_CXX_STD_LIB "")
set (USE_CXX_STD_APP "")
endif()

message(STATUS "C++ VERSION: Setting C++ standard for gnu compiler: lib: ${USE_CXX_STD_LIB} apps: ${USE_CXX_STD_APP}")
message(STATUS "C++: Setting C++ standard for gnu compiler: lib: ${USE_CXX_STD_LIB} apps: ${USE_CXX_STD_APP}")
endif()
else()
set (USE_CXX_STD_LIB "")
set (USE_CXX_STD_APP "")
endif()

if (FORCE_CXX_STANDARD)
set (USE_CXX_STD_APP 11)
message(STATUS "C++ STD: Forcing C++11 on applications")
if (USE_CXX_STD_APP STREQUAL "")
set (USE_CXX_STD_APP 11)
endif()

if (USE_CXX_STD_LIB STREQUAL "" AND ENABLE_STDCXX_SYNC)
message(STATUS "C++ STD: Forcing C++11 on library, as C++11 sync requested")
set (USE_CXX_STD_LIB 11)
endif()
endif()

# add extra warning flags for gccish compilers
Expand Down Expand Up @@ -721,9 +770,23 @@ if (ENABLE_SHARED)
endif()
endif()

if (NOT USE_CXX_STD_LIB STREQUAL "")
set_target_properties(srt_virtual PROPERTIES CXX_STANDARD ${USE_CXX_STD_LIB})
endif()
macro(srt_set_stdcxx targetname spec)
set (stdcxxspec ${spec})
if (NOT "${stdcxxspec}" STREQUAL "")
if (FORCE_CXX_STANDARD_GNUONLY)
target_compile_options(${targetname} PRIVATE -std=c++${stdcxxspec})
#message(STATUS "C++ STD: ${targetname}: forced C++${stdcxxspec} standard - GNU option: -std=c++${stdcxxspec}")
else()
set_target_properties(${targetname} PROPERTIES CXX_STANDARD ${stdcxxspec})
#message(STATUS "C++ STD: ${targetname}: forced C++${stdcxxspec} standard - portable way")
endif()
else()
message(STATUS "APP: ${targetname}: using default C++ standard")
endif()
endmacro()


srt_set_stdcxx(srt_virtual "${USE_CXX_STD_LIB}")

set (VIRTUAL_srt $<TARGET_OBJECTS:srt_virtual>)

Expand Down Expand Up @@ -915,10 +978,9 @@ macro(srt_add_program name)
endmacro()

macro(srt_make_application name)
if (NOT USE_CXX_STD_APP STREQUAL "")
set_target_properties(${name} PROPERTIES CXX_STANDARD ${USE_CXX_STD_APP})
endif()

srt_set_stdcxx(${name} "${USE_CXX_STD_APP}")

# This is recommended by cmake, but it doesn't work anyway.
# What is needed is that this below CMAKE_INSTALL_RPATH (yes, relative)
# is added as is.
Expand Down Expand Up @@ -967,7 +1029,7 @@ endif()

if (ENABLE_APPS)

message(STATUS "APPS: ENABLED")
message(STATUS "APPS: ENABLED, std=${USE_CXX_STD_APP}")

# Make a virtual library of all shared app files
MafReadDir(apps support.maf
Expand All @@ -979,9 +1041,7 @@ if (ENABLE_APPS)
# library should be changed into a static one and made useful
# for users.
add_library(srtsupport_virtual OBJECT ${SOURCES_support})
if (NOT USE_CXX_STD_APP STREQUAL "")
set_target_properties(srtsupport_virtual PROPERTIES CXX_STANDARD ${USE_CXX_STD_APP})
endif()
srt_set_stdcxx(srtsupport_virtual "${USE_CXX_STD_APP}")
set (VIRTUAL_srtsupport $<TARGET_OBJECTS:srtsupport_virtual>)

# Applications
Expand Down Expand Up @@ -1021,14 +1081,13 @@ if (ENABLE_APPS)
endmacro()

srt_add_testprogram(utility-test)
srt_set_stdcxx(utility-test "${USE_CXX_STD_APP}")
if (NOT WIN32)
# This program is symlinked under git-cygwin.
# Avoid misleading syntax error.
srt_add_testprogram(uriparser-test)
target_compile_options(uriparser-test PRIVATE -DTEST)
if (NOT USE_CXX_STD_APP STREQUAL "")
set_target_properties(uriparser-test PROPERTIES CXX_STANDARD ${USE_CXX_STD_APP})
endif()
srt_set_stdcxx(uriparser-test "${USE_CXX_STD_APP}")
endif()

srt_add_testprogram(srt-test-live)
Expand Down
25 changes: 25 additions & 0 deletions docs/BuildOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ usage would still be productive, while without system-supported waiting this
option may increase the likelihood of switching to the right thread at the time
when it is expected to be revived.

**`--use-c++-std=<standard>`**



**`--use-gnustl`**

Expand Down Expand Up @@ -372,3 +375,25 @@ This should be the exact command used as a C compiler, possibly with
version suffix, e.g. `clang-1.7.0`. If this option is used together
with `--with-compiler-prefix`, its prefix will be added in front.

**`--with-extralibs=<library-list>`**

This is an option required for unusual situations when a platform-specific
workaround is needed and some extra libraries must be passed explicitly
for linkage. The argument is a space-separated list of linker options
or library names.

There are some known sitautions where it may be necessary:

1. Some older Linux systems do not ship `clock_gettime` functions by
default in their libc, and need an extra librt. If you are using POSIX
monotonic clocks (see `--enable-monotonic-clock`), this might be required
to add `-lrd` through this option. Although this situation is tried to
be autodetected and this option added automatically, it might sometimes fail.

2. On some systems (found so far on OpenSuSE), if you use C++11 sync
(see `--enable-stdc++-sync`), the gcc compiler relies on gthreads, which
relies on pthreads, and happens to define inline source functions in
the header that refers to `pthread_create`, the compiler however doesn't
link against pthreads by default. To work this around, add `-pthreads`
using this option.

0 comments on commit 10ed37b

Please sign in to comment.