diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-03 15:21:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-03 15:21:27 +0000 |
commit | 60bb8ce74a67345b14fd540dd739254f562c605b (patch) | |
tree | 8a9b1dbad19647f73e2d6dd3b9f816c23330c102 | |
parent | aaf9a7aadf355bb6cb3b33631502f4f77ab43e13 (diff) |
Vendor import of lldb trunk r304659:vendor/lldb/lldb-trunk-r304659
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=319533
svn path=/vendor/lldb/lldb-trunk-r304659/; revision=319534; tag=vendor/lldb/lldb-trunk-r304659
-rw-r--r-- | cmake/modules/LLDBConfig.cmake | 22 | ||||
-rw-r--r-- | cmake/modules/LLDBGenerateConfig.cmake | 9 | ||||
-rw-r--r-- | include/lldb/Host/Config.h.cmake | 4 | ||||
-rw-r--r-- | include/lldb/Host/linux/Uio.h | 3 | ||||
-rw-r--r-- | packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py | 131 | ||||
-rw-r--r-- | source/Host/linux/LibcGlue.cpp | 8 | ||||
-rw-r--r-- | source/Plugins/Platform/MacOSX/PlatformDarwin.cpp | 77 | ||||
-rw-r--r-- | source/Plugins/Platform/MacOSX/PlatformDarwin.h | 8 | ||||
-rw-r--r-- | source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp | 4 | ||||
-rw-r--r-- | source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp | 68 | ||||
-rw-r--r-- | source/Symbol/ClangASTContext.cpp | 5 | ||||
-rw-r--r-- | unittests/CMakeLists.txt | 2 |
12 files changed, 239 insertions, 102 deletions
diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index 79512941fd8d..bbf7a0838d26 100644 --- a/cmake/modules/LLDBConfig.cmake +++ b/cmake/modules/LLDBConfig.cmake @@ -334,28 +334,6 @@ if (HAVE_LIBDL) list(APPEND system_libs ${CMAKE_DL_LIBS}) endif() -# Check for syscall used by lldb-server on linux. -# If these are not found, it will fall back to ptrace (slow) for memory reads. -check_cxx_source_compiles(" - #include <sys/uio.h> - int main() { process_vm_readv(0, nullptr, 0, nullptr, 0, 0); return 0; }" - HAVE_PROCESS_VM_READV) - -if (HAVE_PROCESS_VM_READV) - add_definitions(-DHAVE_PROCESS_VM_READV) -else() - # If we don't have the syscall wrapper function, but we know the syscall number, we can - # still issue the syscall manually - check_cxx_source_compiles(" - #include <sys/syscall.h> - int main() { return __NR_process_vm_readv; }" - HAVE_NR_PROCESS_VM_READV) - - if (HAVE_NR_PROCESS_VM_READV) - add_definitions(-DHAVE_NR_PROCESS_VM_READV) - endif() -endif() - # Figure out if lldb could use lldb-server. If so, then we'll # ensure we build lldb-server when an lldb target is being built. if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD") diff --git a/cmake/modules/LLDBGenerateConfig.cmake b/cmake/modules/LLDBGenerateConfig.cmake index f812cf11614a..d3d0cb220b93 100644 --- a/cmake/modules/LLDBGenerateConfig.cmake +++ b/cmake/modules/LLDBGenerateConfig.cmake @@ -12,6 +12,15 @@ check_symbol_exists(sigaction signal.h HAVE_SIGACTION) check_include_file(termios.h HAVE_TERMIOS_H) check_include_files("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H) +check_cxx_source_compiles(" + #include <sys/uio.h> + int main() { process_vm_readv(0, nullptr, 0, nullptr, 0, 0); return 0; }" + HAVE_PROCESS_VM_READV) +check_cxx_source_compiles(" + #include <sys/syscall.h> + int main() { return __NR_process_vm_readv; }" + HAVE_NR_PROCESS_VM_READV) + # These checks exist in LLVM's configuration, so I want to match the LLVM names # so that the check isn't duplicated, but we translate them into the LLDB names # so that I don't have to change all the uses at the moment. diff --git a/include/lldb/Host/Config.h.cmake b/include/lldb/Host/Config.h.cmake index 5a16425fe0a9..0deedd151a5e 100644 --- a/include/lldb/Host/Config.h.cmake +++ b/include/lldb/Host/Config.h.cmake @@ -20,4 +20,8 @@ #cmakedefine01 HAVE_SIGACTION +#cmakedefine01 HAVE_PROCESS_VM_READV + +#cmakedefine01 HAVE_NR_PROCESS_VM_READV + #endif // #ifndef LLDB_HOST_CONFIG_H diff --git a/include/lldb/Host/linux/Uio.h b/include/lldb/Host/linux/Uio.h index 8b964d3f3e25..0b8b7dbf6fb9 100644 --- a/include/lldb/Host/linux/Uio.h +++ b/include/lldb/Host/linux/Uio.h @@ -10,11 +10,12 @@ #ifndef liblldb_Host_linux_Uio_h_ #define liblldb_Host_linux_Uio_h_ +#include "lldb/Host/Config.h" #include <sys/uio.h> // We shall provide our own implementation of process_vm_readv if it is not // present -#ifndef HAVE_PROCESS_VM_READV +#if !HAVE_PROCESS_VM_READV ssize_t process_vm_readv(::pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags); diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py b/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py index add3f7a01ad6..96c5a33f14b0 100644 --- a/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py +++ b/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py @@ -26,16 +26,7 @@ class ObjCNewSyntaxTestCase(TestBase): # Find the line number to break inside main(). self.line = line_number('main.m', '// Set breakpoint 0 here.') - @skipUnlessDarwin - @expectedFailureAll( - oslist=['macosx'], - compiler='clang', - compiler_version=[ - '<', - '7.0.0']) - @skipIf(macos_version=["<", "10.12"]) - @expectedFailureAll(archs=["i[3-6]86"]) - def test_expr(self): + def runToBreakpoint(self): self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -55,6 +46,18 @@ class ObjCNewSyntaxTestCase(TestBase): self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs=[' resolved, hit count = 1']) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_read_array(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- immutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY, @@ -65,6 +68,18 @@ class ObjCNewSyntaxTestCase(TestBase): VARIABLES_DISPLAYED_CORRECTLY, substrs=["foo"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_update_array(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- mutable_array[0] = @\"bar\"", VARIABLES_DISPLAYED_CORRECTLY, @@ -75,6 +90,18 @@ class ObjCNewSyntaxTestCase(TestBase): VARIABLES_DISPLAYED_CORRECTLY, substrs=["bar"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_read_dictionary(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- immutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY, @@ -85,6 +112,18 @@ class ObjCNewSyntaxTestCase(TestBase): VARIABLES_DISPLAYED_CORRECTLY, substrs=["value"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_update_dictionary(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- mutable_dictionary[@\"key\"] = @\"object\"", VARIABLES_DISPLAYED_CORRECTLY, @@ -95,6 +134,18 @@ class ObjCNewSyntaxTestCase(TestBase): VARIABLES_DISPLAYED_CORRECTLY, substrs=["object"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_array_literal(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- @[ @\"foo\", @\"bar\" ]", VARIABLES_DISPLAYED_CORRECTLY, @@ -103,6 +154,18 @@ class ObjCNewSyntaxTestCase(TestBase): "foo", "bar"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_dictionary_literal(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- @{ @\"key\" : @\"object\" }", VARIABLES_DISPLAYED_CORRECTLY, @@ -110,9 +173,33 @@ class ObjCNewSyntaxTestCase(TestBase): "key", "object"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_char_literal(self): + self.runToBreakpoint() + self.expect("expr --object-description -- @'a'", VARIABLES_DISPLAYED_CORRECTLY, substrs=[str(ord('a'))]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_integer_literals(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- @1", VARIABLES_DISPLAYED_CORRECTLY, @@ -138,9 +225,33 @@ class ObjCNewSyntaxTestCase(TestBase): VARIABLES_DISPLAYED_CORRECTLY, substrs=["1"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_float_literal(self): + self.runToBreakpoint() + self.expect("expr -- @123.45", VARIABLES_DISPLAYED_CORRECTLY, substrs=["NSNumber", "123.45"]) + @skipUnlessDarwin + @expectedFailureAll( + oslist=['macosx'], + compiler='clang', + compiler_version=[ + '<', + '7.0.0']) + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_expressions_in_literals(self): + self.runToBreakpoint() + self.expect( "expr --object-description -- @( 1 + 3 )", VARIABLES_DISPLAYED_CORRECTLY, diff --git a/source/Host/linux/LibcGlue.cpp b/source/Host/linux/LibcGlue.cpp index c036bb28a9bc..93d2a41d2eb1 100644 --- a/source/Host/linux/LibcGlue.cpp +++ b/source/Host/linux/LibcGlue.cpp @@ -14,13 +14,13 @@ #include <sys/syscall.h> #include <unistd.h> -#ifndef HAVE_PROCESS_VM_READV // If the syscall wrapper is not available, - // provide one. +#if !HAVE_PROCESS_VM_READV +// If the syscall wrapper is not available, provide one. ssize_t process_vm_readv(::pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags) { -#ifdef HAVE_NR_PROCESS_VM_READV // If we have the syscall number, we can issue - // the syscall ourselves. +#if HAVE_NR_PROCESS_VM_READV + // If we have the syscall number, we can issue the syscall ourselves. return syscall(__NR_process_vm_readv, pid, local_iov, liovcnt, remote_iov, riovcnt, flags); #else // If not, let's pretend the syscall is not present. diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index d69a02e41d51..a29cc9e1ed86 100644 --- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -33,6 +33,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferLLVM.h" @@ -1763,3 +1764,79 @@ PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) { // Let our parent class do the real launching. return PlatformPOSIX::LaunchProcess(launch_info); } + +lldb_private::Status +PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec, Process *process, + ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + ModuleSP *old_module_sp_ptr, bool *did_create_ptr) +{ + const FileSpec &platform_file = module_spec.GetFileSpec(); + // See if the file is present in any of the module_search_paths_ptr directories. + if (!module_sp && module_search_paths_ptr && platform_file) { + // create a vector of all the file / directory names in platform_file + // e.g. this might be + // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation + // + // We'll need to look in the module_search_paths_ptr directories for + // both "UIFoundation" and "UIFoundation.framework" -- most likely the + // latter will be the one we find there. + + FileSpec platform_pull_apart(platform_file); + std::vector<std::string> path_parts; + ConstString unix_root_dir("/"); + while (true) { + ConstString part = platform_pull_apart.GetLastPathComponent(); + platform_pull_apart.RemoveLastPathComponent(); + if (part.IsEmpty() || part == unix_root_dir) + break; + path_parts.push_back(part.AsCString()); + } + const size_t path_parts_size = path_parts.size(); + + size_t num_module_search_paths = module_search_paths_ptr->GetSize(); + for (size_t i = 0; i < num_module_search_paths; ++i) { + Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (log_verbose) + log_verbose->Printf ("PlatformRemoteDarwinDevice::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str()); + // Create a new FileSpec with this module_search_paths_ptr + // plus just the filename ("UIFoundation"), then the parent + // dir plus filename ("UIFoundation.framework/UIFoundation") + // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo") + + for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) { + FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i)); + + // Add the components backwards. For + // .../PrivateFrameworks/UIFoundation.framework/UIFoundation + // path_parts is + // [0] UIFoundation + // [1] UIFoundation.framework + // [2] PrivateFrameworks + // + // and if 'j' is 2, we want to append path_parts[1] and then + // path_parts[0], aka + // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr + // path. + + for (int k = j; k >= 0; --k) { + path_to_try.AppendPathComponent(path_parts[k]); + } + + if (path_to_try.Exists()) { + ModuleSpec new_module_spec(module_spec); + new_module_spec.GetFileSpec() = path_to_try; + Status new_error(Platform::GetSharedModule( + new_module_spec, process, module_sp, NULL, old_module_sp_ptr, + did_create_ptr)); + + if (module_sp) { + module_sp->SetPlatformFileSpec(path_to_try); + return new_error; + } + } + } + } + } + return Status(); +} diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h index 6495609ac495..c04318e98cae 100644 --- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -128,9 +128,15 @@ protected: std::vector<std::string> &options, SDKType sdk_type); + const char *GetDeveloperDirectory(); + + lldb_private::Status + FindBundleBinaryInExecSearchPaths (const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, + lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); + std::string m_developer_directory; - const char *GetDeveloperDirectory(); private: DISALLOW_COPY_AND_ASSIGN(PlatformDarwin); diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp index c08417a80ae4..43f4d8bbf023 100644 --- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -339,5 +339,9 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( } } } + + if (!module_sp) { + error = FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + } return error; } diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp index f7395fb8cf3d..ea44714a916e 100644 --- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp +++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp @@ -605,70 +605,12 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( // See if the file is present in any of the module_search_paths_ptr // directories. - if (!module_sp && module_search_paths_ptr && platform_file) { - // create a vector of all the file / directory names in platform_file - // e.g. this might be - // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation - // - // We'll need to look in the module_search_paths_ptr directories for - // both "UIFoundation" and "UIFoundation.framework" -- most likely the - // latter will be the one we find there. - - FileSpec platform_pull_apart(platform_file); - std::vector<std::string> path_parts; - ConstString unix_root_dir("/"); - while (true) { - ConstString part = platform_pull_apart.GetLastPathComponent(); - platform_pull_apart.RemoveLastPathComponent(); - if (part.IsEmpty() || part == unix_root_dir) - break; - path_parts.push_back(part.AsCString()); - } - const size_t path_parts_size = path_parts.size(); - - size_t num_module_search_paths = module_search_paths_ptr->GetSize(); - for (size_t i = 0; i < num_module_search_paths; ++i) { - LLDB_LOGV(log, "searching for binary in search-path {0}", - module_search_paths_ptr->GetFileSpecAtIndex(i)); - // Create a new FileSpec with this module_search_paths_ptr - // plus just the filename ("UIFoundation"), then the parent - // dir plus filename ("UIFoundation.framework/UIFoundation") - // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo") - - for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) { - FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i)); - - // Add the components backwards. For - // .../PrivateFrameworks/UIFoundation.framework/UIFoundation - // path_parts is - // [0] UIFoundation - // [1] UIFoundation.framework - // [2] PrivateFrameworks - // - // and if 'j' is 2, we want to append path_parts[1] and then - // path_parts[0], aka - // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr - // path. - - for (int k = j; k >= 0; --k) { - path_to_try.AppendPathComponent(path_parts[k]); - } - - if (path_to_try.Exists()) { - ModuleSpec new_module_spec(module_spec); - new_module_spec.GetFileSpec() = path_to_try; - Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, NULL, old_module_sp_ptr, - did_create_ptr)); + if (!module_sp) + error = PlatformDarwin::FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, + module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); - if (module_sp) { - module_sp->SetPlatformFileSpec(path_to_try); - return new_error; - } - } - } - } - } + if (error.Success()) + return error; const bool always_create = false; error = ModuleList::GetSharedModule( diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 94c91fe335a7..c8738e6e5502 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -3938,6 +3938,11 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { + case clang::Type::Attributed: + return GetTypeInfo( + qual_type->getAs<clang::AttributedType>() + ->getModifiedType().getAsOpaquePtr(), + pointee_or_element_clang_type); case clang::Type::Builtin: { const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>( qual_type->getCanonicalTypeInternal()); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index f4c735e78e34..f78879db09b4 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -40,7 +40,7 @@ function(add_lldb_unittest test_name) POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Inputs) - target_link_libraries(${test_name} ${ARG_LINK_LIBS} ${CLANG_USED_LIBS} ${LLDB_SYSTEM_LIBS}) + target_link_libraries(${test_name} ${ARG_LINK_LIBS} ${LLDB_SYSTEM_LIBS}) endfunction() function(add_unittest_inputs test_name inputs) |