diff --git a/emcc b/emcc index 7ed0adb29..5b6d1063f 100755 --- a/emcc +++ b/emcc @@ -540,6 +540,15 @@ for i in range(len(sys.argv)-1): sys.argv = sys.argv[:i] + sys.argv[i+2:] break +specified_target = target +target = specified_target if specified_target is not None else 'a.out.js' # specified_target is the user-specified one, target is what we will generate +target_basename = unsuffixed_basename(target) + +if '.' in target: + final_suffix = target.split('.')[-1] +else: + final_suffix = '' + if header: # header or such if len(sys.argv) >= 3: # if there is a source and a target, then copy, otherwise do nothing sys.argv = filter(lambda arg: not arg.startswith('-I'), sys.argv) @@ -789,6 +798,17 @@ try: newargs = [ arg for arg in newargs if arg is not '' ] + # -c means do not link in gcc, and for us, the parallel is to not go all the way to JS, but stop at bitcode + has_dash_c = '-c' in newargs + if has_dash_c: + assert has_source_inputs, 'Must have source code inputs to use -c' + target = target_basename + '.o' + final_suffix = 'o' + + # do not link in libs when just generating object code (not an 'executable', i.e. JS, or a library) + if ('.' + final_suffix) in BITCODE_SUFFIXES: + libs = [] + # Find library files for lib in libs: if DEBUG: print >> sys.stderr, 'emcc: looking for library "%s"' % lib @@ -816,22 +836,6 @@ try: newargs += CC_ADDITIONAL_ARGS - specified_target = target - target = specified_target if specified_target is not None else 'a.out.js' # specified_target is the user-specified one, target is what we will generate - - target_basename = unsuffixed_basename(target) - - # -c means do not link in gcc, and for us, the parallel is to not go all the way to JS, but stop at bitcode - has_dash_c = '-c' in newargs - if has_dash_c: - assert has_source_inputs, 'Must have source code inputs to use -c' - target = target_basename + '.o' - - if '.' in target: - final_suffix = target.split('.')[-1] - else: - final_suffix = '' - assert not (Compression.on and final_suffix != 'html'), 'Compression only works when generating HTML' # If we are using embind and generating JS, now is the time to link in bind.cpp @@ -904,7 +908,7 @@ try: assert len(original_input_files) == 1 or not has_dash_c, 'fatal error: cannot specify -o with -c with multiple files' + str(sys.argv) + ':' + str(original_input_files) # We have a specified target (-o ), which is not JavaScript or HTML, and # we have multiple files: Link them - if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(temp_files) + if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(temp_files), specified_target shared.Building.link(temp_files, specified_target, remove_duplicates=remove_duplicates) exit(0) diff --git a/tests/runner.py b/tests/runner.py index cef14e95b..f024198ea 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7850,6 +7850,36 @@ f.close() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) assert not os.path.exists('a.out') and not os.path.exists('a.exe'), 'Must not leave unneeded linker stubs' + def test_multiply_defined_libsymbols(self): + lib = "int mult() { return 1; }" + lib_name = os.path.join(self.get_dir(), 'libA.c') + open(lib_name, 'w').write(lib) + a2 = "void x() {}" + a2_name = os.path.join(self.get_dir(), 'a2.c') + open(a2_name, 'w').write(a2) + b2 = "void y() {}" + b2_name = os.path.join(self.get_dir(), 'b2.c') + open(b2_name, 'w').write(b2) + main = r''' + #include + int mult(); + int main() { + printf("result: %d\n", mult()); + return 0; + } + ''' + main_name = os.path.join(self.get_dir(), 'main.c') + open(main_name, 'w').write(main) + + Building.emcc(lib_name, output_filename='libA.so') + + Building.emcc(a2_name, ['-L.', '-lA']) + Building.emcc(b2_name, ['-L.', '-lA']) + + Building.emcc(main_name, ['-L.', '-lA', a2_name+'.o', b2_name+'.o'], output_filename='a.out.js') + + self.assertContained('result: 1', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_abspaths(self): # Includes with absolute paths are generally dangerous, things like -I/usr/.. will get to system local headers, not our portable ones.