In my example code:
main.cpp
#include <iostream>
#if defined(_WIN32) || defined(__WIN32__)
#define EXPORT extern "C" __declspec(dllexport)
#elif defined(linux) || defined(__linux)
#define EXPORT __attribute__((visibility("default")))
#endif
EXPORT void hello()
{
std::cout<<"Hello world!"<<std::endl;
}
/* not exported */ void goodbye()
{
std::cout<<"Goodbye!"<<std::endl;
}
compiled via options as followed:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.9)
project(my_test)
add_library(output SHARED
main.cpp
)
set(CMAKE_CXX_COMPILER "g ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s -Wall -Wextra -std=c 17 -fvisibility=hidden -fvisibility-inlines-hidden")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections")
#set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections -Wl,--strip-all")
I see symbols rather than the hello
function:
nm -D liboutput.so
The result:
U __cxa_atexit
w __cxa_finalize
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000001179 T _Z5hellov
U _ZNSolsEPFRSoS_E
U _ZNSt8ios_base4InitC1Ev
U _ZNSt8ios_base4InitD1Ev
U _ZSt4cout
U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
I do not want the functions such as _ZSt4cout
be visible from outside. My problem is not solved even if I enable the last two lines of the cmake recipe.
How can I achieve that?
CodePudding user response:
Your approach is correct but your program contains some undefined symbols which need to be imported from libstdc
at startup (e.g. std::cout
). Linker has to insert such symbols in your library's symbol table, otherwise loader won't know that they need to be imported.
You can link against static version of STL (via -static-libstdc
) and apply a version script to prevent linker from exporting STL symbols from your shared library:
$ cat foo.map
{
global:
_Z3foov; # Export only foo
local: *; # Hide everything else
};
$ g tmp.o -fPIC -shared -static-libstdc -Wl,--version-script=foo.map
Note that linking STL statically will cause code bloat.