Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build: Support static linked executable #4152

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions trunk/auto/options.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ SRS_JOBS=1
# If enabled, force to use SRS_JOBS for make on linux, however you're able to overwrite by -jN on macOS.
SRS_FORCE_MAKE_JOBS=YES
SRS_STATIC=NO
SRS_STATIC_STD_CPP=NO
# If enabled, link shared libraries for libst.so which uses MPL license.
# See https://ossrs.net/lts/zh-cn/license#state-threads
SRS_SHARED_ST=NO
Expand Down Expand Up @@ -205,6 +206,7 @@ Performance: @see https://ossrs.net/lts/zh-cn/docs/v5/doc/perform

Toolchain options:
--static=on|off Whether add '-static' to link options. Default: $(value2switch $SRS_STATIC)
--static-stdcpp=on|off Whether add '-static-libstdc++' to link options. Default: $(value2switch $SRS_STATIC_STD_CPP)
--cc=<CC> Toolchain: Use c compiler CC. Default: $SRS_TOOL_CC
--cxx=<CXX> Toolchain: Use c++ compiler CXX. Default: $SRS_TOOL_CXX
--ar=<AR> Toolchain: Use archive tool AR. Default: $SRS_TOOL_CXX
Expand Down Expand Up @@ -306,6 +308,7 @@ function parse_user_option() {
--config) SRS_DEFAULT_CONFIG=${value} ;;

--static) SRS_STATIC=$(switch2value $value) ;;
--static-stdcpp) SRS_STATIC_STD_CPP=$(switch2value $value) ;;
--cpu) SRS_CROSS_BUILD_CPU=${value} ;;
--arch) SRS_CROSS_BUILD_ARCH=${value} ;;
--host) SRS_CROSS_BUILD_HOST=${value} ;;
Expand Down Expand Up @@ -663,6 +666,7 @@ function regenerate_options() {
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gcp=$(value2switch $SRS_GPERF_CP)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gprof=$(value2switch $SRS_GPROF)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --static=$(value2switch $SRS_STATIC)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --static-stdcpp=$(value2switch $SRS_STATIC_STD_CPP)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --shared-st=$(value2switch $SRS_SHARED_ST)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --shared-srt=$(value2switch $SRS_SHARED_SRT)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --shared-ffmpeg=$(value2switch $SRS_SHARED_FFMPEG)"
Expand Down Expand Up @@ -755,6 +759,24 @@ function check_option_conflicts() {
if [[ $SRS_GPERF_CP == RESERVED ]]; then echo "you must specifies the gperf-cp, see: ./configure --help"; __check_ok=NO; fi
if [[ $SRS_GPROF == RESERVED ]]; then echo "you must specifies the gprof, see: ./configure --help"; __check_ok=NO; fi
if [[ -z $SRS_PREFIX ]]; then echo "you must specifies the prefix, see: ./configure --prefix"; __check_ok=NO; fi
if [[ $SRS_STATIC == YES && $OS_IS_LINUX != YES ]]; then
echo ""
echo -e "${RED}Mac OS X does not support statically linked executable binaries.${BLACK}"
echo -e "@see: ${YELLOW}https://developer.apple.com/library/archive/qa/qa1118/_index.html${BLACK}"
echo -e "${YELLOW}CYGWIN platform not verified.${BLACK}"
echo ""
__check_ok=NO;
fi
if [[ $SRS_STATIC_STD_CPP == YES && $OS_IS_LINUX != YES ]]; then
echo ""
echo -e "${YELLOW}-static-libstd++ is unused in Mac OS X.${BLACK}"
echo -e "${YELLOW}CYGWIN platform not verified.${BLACK}"
fi
if [[ $SRS_STATIC == YES && $SRS_STATIC_STD_CPP == YES ]]; then
echo ""
echo -e "${YELLOW}--static and --static-stdcpp are both on, only keep --static=on${BLACK}"
SRS_STATIC_STD_CPP=NO
fi
if [[ $__check_ok == NO ]]; then
exit 1;
fi
Expand Down
4 changes: 4 additions & 0 deletions trunk/configure
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ fi
# so we need to link the c++ libraries staticly but not all.
# @see https://stackoverflow.com/a/26107550
if [[ $SRS_STATIC == YES ]]; then
Copy link
Member

@winlinvip winlinvip Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why need SRS_STATIC_STD_CPP? Maybe we should only support SRS_STATIC which leads to -static-libstdc++ -static?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-static will generate a static linked executer,
-static-libstdc++ only link the static libstdc++ library.
So -static will cover -static-libstdc++ scope, I think it's no need to combine -static -static-libstdc++ together.

https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

Copy link
Member

@winlinvip winlinvip Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the output if use -static without -static-libstdc++? User only want a static binary without depends, majority of users can't understand the nuance of these two options.

Copy link
Contributor Author

@suzp1984 suzp1984 Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux:

-static output:

docker run -it --rm -v `pwd`:/srs -w /srs ossrs/srs:ubuntu20 bash -c "./configure --static=on && make"

/usr/bin/ld: ./objs/src/kernel/srs_kernel_error.o: in function `parse_symbol_offset(char*)':
/srs/./src/kernel/srs_kernel_error.cpp:73: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ./objs/src/kernel/srs_kernel_utility.o: in function `srs_dns_resolve(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int&)':
/srs/./src/kernel/srs_kernel_utility.cpp:161: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ./objs/openssl/lib/libcrypto.a(b_sock.o): in function `BIO_gethostbyname':
b_sock.c:(.text+0x78): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
make[1]: Leaving directory '/srs'

The warning said: dlopen, getaddrinfo and gethostbyname requires libc similar runtime shared library to support.

docker run -it --rm -v `pwd`:/srs -w /srs ossrs/srs:ubuntu20 bash -c "ldd ./objs/srs"

not a dynamic executable

with both -static -static-ibstdc++

same warning like -static.
ldd ./objs/srs
same output: not a dynamic executable.

git show 6314c27

on above commit, SRS_STATIC use -static-libstdc++ to replace -static.
But I think keep fully static linked exec can be an option, but not recommended.

Copy link
Member

@winlinvip winlinvip Aug 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon investigation, when we utilize certain functions such as dlopen and gethostbyname, we cannot achieve complete static linking, even though we use the -static flag; full static linking is not possible.

Only by removing the dependencies on these functions can we fully utilize the -static flag to create a version that truly does not depend on glibc.

Therefore, it is necessary to remove the dependencies on these functions. The dependency on dlopen comes from third-party libraries, which might be removed through compilation options. Functions like gethostbyname may require the use of different libraries or an implementation by the ST team itself.

https://stackoverflow.com/questions/15165306/compile-a-static-binary-which-code-there-a-function-gethostbyname

xmrig/xmrig#2902

https://www.reddit.com/r/haskell/comments/vqqq7x/comment/iez099a/

TRANS_BY_GPT4

Copy link
Member

@winlinvip winlinvip Aug 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To facilitate full static linking, we can only support the -static option, rather than also having a -static-libstdc++ option, which users might not understand how to use.

Essentially, when we support -static, a multitude of warnings are generated. These warnings actually indicate potential issues, hence our support for -static is not robust and leaves underlying problems unresolved.

We absolutely cannot offer an option that carries potential risks, as it would make any arising issues even more difficult to address.

TRANS_BY_GPT4

SrsLinkOptions="${SrsLinkOptions} -static";
fi

if [[ $SRS_STATIC_STD_CPP == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -static-libstdc++";
fi

Expand Down
Loading