diff --git a/modules/CDTMacros.cmake.in b/modules/CDTMacros.cmake.in index 01fdff9195..3a280651e8 100644 --- a/modules/CDTMacros.cmake.in +++ b/modules/CDTMacros.cmake.in @@ -20,11 +20,10 @@ endmacro() macro (add_native_library TARGET) add_library( ${TARGET} ${ARGN} ) - target_compile_options( ${TARGET} PUBLIC -fnative ) + target_compile_options( ${TARGET} PUBLIC -fnative -fPIC ) endmacro() macro (add_native_executable TARGET) - cmake_policy(SET CMP0002 OLD) add_executable( ${TARGET} ${ARGN} ) target_compile_options( ${TARGET} PUBLIC -fnative ) set_target_properties( ${TARGET} PROPERTIES LINK_FLAGS "-fnative" SUFFIX "" ) @@ -38,3 +37,17 @@ macro (add_native_executable TARGET) endif() endmacro() +macro (add_native_shared_lib TARGET) + set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) + add_library( ${TARGET} SHARED ${ARGN} ) + target_compile_options( ${TARGET} PUBLIC -fnative ) + get_target_property(BINOUTPUT ${TARGET} BINARY_DIR) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND APPLE) + target_compile_options( ${TARGET} PUBLIC -g ) + find_program ( name NAMES "dsymutil" ) + if ( name ) + add_custom_command( TARGET ${TARGET} POST_BUILD COMMAND dsymutil ${BINOUTPUT}/${TARGET} ) + endif() + endif() +endmacro() + diff --git a/modules/CDTWasmToolchain.cmake.in b/modules/CDTWasmToolchain.cmake.in index c22b1a7a85..4343fdb787 100644 --- a/modules/CDTWasmToolchain.cmake.in +++ b/modules/CDTWasmToolchain.cmake.in @@ -21,6 +21,7 @@ set(WASM_LINKER "@CDT_ROOT_DIR@/bin/cdt-ld") set(CMAKE_C_LINK_EXECUTABLE "${WASM_LINKER} -o ") set(CMAKE_CXX_LINK_EXECUTABLE "${WASM_LINKER} -o ") +set(CMAKE_CXX_CREATE_SHARED_LIBRARY "${WASM_LINKER} -shared -o ") set(CMAKE_EXECUTABLE_SUFFIX_C ".wasm") set(CMAKE_EXECUTABLE_SUFFIX_CXX ".wasm") diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index ef68d49005..d5a6eeab10 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -27,7 +27,6 @@ add_cdt_unit_test(string_tests1) add_cdt_unit_test(string_tests2) add_cdt_unit_test(symbol_tests) add_cdt_unit_test(system_tests) -add_cdt_unit_test(rope_tests) add_cdt_unit_test(print_tests) add_cdt_unit_test(time_tests) add_cdt_unit_test(varint_tests) diff --git a/tools/include/compiler_options.hpp.in b/tools/include/compiler_options.hpp.in index 7ffa880d2c..875ed5c538 100644 --- a/tools/include/compiler_options.hpp.in +++ b/tools/include/compiler_options.hpp.in @@ -131,6 +131,11 @@ static cl::opt fnative_opt( cl::desc("Compile and link for x86-64"), cl::ZeroOrMore, cl::cat(LD_CAT)); +static cl::opt fshared_opt( + "shared", + cl::desc("Make shared object native library"), + cl::ZeroOrMore, + cl::cat(LD_CAT)); static cl::opt fuse_main_opt( "fuse-main", cl::desc("Use main as entry"), @@ -355,6 +360,11 @@ static cl::opt warn_action_read_only_opt( "warn-action-read-only", cl::desc("Issue a warning if a read-only action uses a write API and continue compilation"), cl::cat(EosioCompilerToolCategory)); +static cl::opt fPIC_opt( + "fPIC", + cl::desc("Generate position independent code. This option is used for shared libraries"), + cl::Optional, + cl::cat(LD_CAT)); /// end c/c++ options /// begin c++ options @@ -391,6 +401,7 @@ struct Options { std::vector abigen_resources; bool debug; bool native; + bool shared_lib; std::pair abi_version; bool has_o_opt; bool has_contract_opt; @@ -404,7 +415,7 @@ static void GetCompDefaults(std::vector& copts) { copts.emplace_back(std::string("-D__eosio_cdt_major__=")+"${VERSION_MAJOR}"); copts.emplace_back(std::string("-D__eosio_cdt_minor__=")+"${VERSION_MINOR}"); copts.emplace_back(std::string("-D__eosio_cdt_patchlevel__=")+"${VERSION_PATCH}"); - if (!fnative_opt) { + if (!fnative_opt && !fshared_opt) { copts.emplace_back("--target=wasm32"); copts.emplace_back("-ffreestanding"); copts.emplace_back("-nostdlib"); @@ -439,7 +450,7 @@ static void GetCompDefaults(std::vector& copts) { copts.emplace_back("-DBOOST_DISABLE_ASSERTS"); copts.emplace_back("-DBOOST_EXCEPTION_DISABLE"); copts.emplace_back("-U__APPLE__"); - if (!fnative_opt) { + if (!fnative_opt && !fshared_opt) { copts.emplace_back("-Xclang"); copts.emplace_back("-load"); copts.emplace_back("-Xclang"); @@ -466,7 +477,7 @@ static void GetCompDefaults(std::vector& copts) { #ifdef ONLY_LD static void GetLdDefaults(std::vector& ldopts) { - if (!fnative_opt) { + if (!fnative_opt && !fshared_opt) { if (!allow_names_opt) { ldopts.emplace_back("--gc-sections"); ldopts.emplace_back("--strip-all"); @@ -536,13 +547,22 @@ static void GetLdDefaults(std::vector& ldopts) { #ifdef __APPLE__ ldopts.insert(ldopts.end(), {"-arch", "x86_64", "-macosx_version_min", "10.13", "-framework", "Foundation", "-framework", "System"}); #endif - ldopts.emplace_back("-static"); - ldopts.insert(ldopts.end(), {"-lnative_c++", "-lnative_c", "-lnative_eosio", "-lnative", "-lnative_rt"}); + if (fshared_opt) { + ldopts.emplace_back("-shared"); + } + else { + ldopts.emplace_back("-static"); + } + ldopts.insert(ldopts.end(), {"-Bstatic", "-lnative_c++", "-lnative_c", "-lnative_eosio", "-lnative", "-lnative_rt"}); } } #endif static Options CreateOptions(bool add_defaults=true) { + if (fshared_opt && fnative_opt) { + throw std::runtime_error("Both -fnative and -fshared was specified. Only one of them should be present."); + } + std::string output_fn; std::vector inputs; std::vector agresources; @@ -722,7 +742,7 @@ static Options CreateOptions(bool add_defaults=true) { copts.emplace_back("-I"+sysroot_opt+"/include/libc"); // only allow capi for native builds and for eosio-cc - if (fnative_opt) { + if (fnative_opt || fshared_opt) { copts.emplace_back("-I"+sysroot_opt+"/include/eosiolib/capi"); copts.emplace_back("-I"+sysroot_opt+"/include/eosiolib/native"); } @@ -748,7 +768,7 @@ static Options CreateOptions(bool add_defaults=true) { agopts.emplace_back("--sysroot="+eosio::cdt::whereami::where()+"/../"); ldopts.emplace_back("-L"+eosio::cdt::whereami::where()+"/../lib"); - if (fnative_opt) { + if (fnative_opt || fshared_opt) { copts.emplace_back("-I"+eosio::cdt::whereami::where()+"/../include/eosiolib/capi"); copts.emplace_back("-I"+eosio::cdt::whereami::where()+"/../include/eosiolib/native"); } @@ -787,8 +807,12 @@ static Options CreateOptions(bool add_defaults=true) { copts.emplace_back("-W"+warn); } + if (fPIC_opt) { + copts.emplace_back("-fPIC"); + } + #endif - if (!fnative_opt) { + if (!fnative_opt && !fshared_opt) { #ifdef ONLY_LD if (stack_canary_opt) { ldopts.emplace_back("--stack-canary"); @@ -828,11 +852,22 @@ static Options CreateOptions(bool add_defaults=true) { for ( auto library : l_opt ) { ldopts.emplace_back("-l"+library); } + auto replace_extension = [&](auto& str){ + if (fnative_opt) { + llvm::sys::path::replace_extension(str, ""); + } + else if (fshared_opt) { + llvm::sys::path::replace_extension(str, ".so"); + } + else { + llvm::sys::path::replace_extension(str, ".wasm"); + } + }; if (o_opt.empty()) { #ifndef ONLY_LD if (inputs.size() == 1) { llvm::SmallString<256> fn = llvm::sys::path::filename(inputs[0]); - llvm::sys::path::replace_extension(fn, fnative_opt ? "" : ".wasm"); + replace_extension(fn); output_fn = fn.str(); } else { ldopts.emplace_back("a.out"); @@ -841,7 +876,7 @@ static Options CreateOptions(bool add_defaults=true) { if (inputs.size() == 1) { llvm::SmallString<256> fn = llvm::sys::path::filename(inputs[0]); llvm::sys::path::replace_extension(fn, ""); - llvm::sys::path::replace_extension(fn, fnative_opt ? "" : ".wasm"); + replace_extension(fn); output_fn = fn.str(); ldopts.emplace_back("-o"+output_fn); } else { @@ -858,7 +893,7 @@ static Options CreateOptions(bool add_defaults=true) { has_o_opt = true; } - if (!fnative_opt) { + if (!fnative_opt && !fshared_opt) { #ifndef ONLY_LD if (!imports_opt.empty()) { ldopts.emplace_back("-imports="+imports_opt); @@ -915,6 +950,9 @@ static Options CreateOptions(bool add_defaults=true) { } if (fnative_opt) ldopts.emplace_back("-fnative"); + else if (fshared_opt) { + ldopts.emplace_back("-shared"); + } if (fuse_main_opt) ldopts.emplace_back("-fuse-main"); @@ -937,8 +975,8 @@ static Options CreateOptions(bool add_defaults=true) { } #ifndef ONLY_LD - return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt, warn_action_read_only}; + return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, fshared_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt, warn_action_read_only}; #else - return {output_fn, {}, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt, warn_action_read_only}; + return {output_fn, {}, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, fshared_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt, warn_action_read_only}; #endif } diff --git a/tools/ld/cdt-ld.cpp.in b/tools/ld/cdt-ld.cpp.in index 6bb649c800..89fda6a7cd 100644 --- a/tools/ld/cdt-ld.cpp.in +++ b/tools/ld/cdt-ld.cpp.in @@ -22,7 +22,7 @@ int main(int argc, const char **argv) { Options opts = CreateOptions(); std::string line; - if (opts.native) { + if (opts.native || opts.shared_lib) { #ifdef __APPLE__ if (!eosio::cdt::environment::exec_subprogram("ld", opts.ld_options, true)) #else @@ -41,7 +41,7 @@ int main(int argc, const char **argv) { } // finally any post processing - if (!fno_post_pass_opt && !opts.native) { + if (!fno_post_pass_opt && !opts.native && !opts.shared_lib) { if ( !llvm::sys::fs::exists( opts.eosio_pp_dir+"/eosio-pp" ) ) { std::cerr << "Error: eosio.pp not found! (Try reinstalling eosio.cdt)" << std::endl; return -1;