convert a static library to a dynamic one?

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

convert a static library to a dynamic one?

Mark Brethen-2
The spooles src creates a static ‘spooles.a’ library. I want to get a dynamic library out of it. In BSD, for a .so library you would use:

ld -Bshareable -o libspooles.so.1 -x -soname libspooles.so.1 --whole-archive spooles.a

For macports I tried

system -W ${worksrcpath}_SHARED ld -dylib -force_load spooles.a -o libspooles.1.dylib

ld fails with an error:

:info:build ld: symbol(s) not found for inferred architecture x86_64
:info:build Command failed: ld -dylib -force_load spooles.a -o libspooles.1.dylib
:info:build Exit code: 1
:error:build Failed to build spooles: command execution failed

How do I have to modify above command so I will get the desired result?


Mark Brethen
[hidden email]



Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Rainer Müller-4
On 18.11.18 20:36, Mark Brethen wrote:

> The spooles src creates a static ‘spooles.a’ library. I want to get a dynamic library out of it. In BSD, for a .so library you would use:
>
> ld -Bshareable -o libspooles.so.1 -x -soname libspooles.so.1 --whole-archive spooles.a
>
> For macports I tried
>
> system -W ${worksrcpath}_SHARED ld -dylib -force_load spooles.a -o libspooles.1.dylib
>
> ld fails with an error:
>
> :info:build ld: symbol(s) not found for inferred architecture x86_64
> :info:build Command failed: ld -dylib -force_load spooles.a -o libspooles.1.dylib
> :info:build Exit code: 1
> :error:build Failed to build spooles: command execution failed
>
> How do I have to modify above command so I will get the desired result?

I would have extracted the object files from the archive and created a
dynamic library using libtool (that is /usr/bin/libtool, not to be
confused with GNU libtool).

  ar -x spooles.a
  libtool -dynamic *.o -o libspooles.1.dylib

You most likely should also set additional arguments such as
-install_name and -compatibility_version/-current_version if you want to
distribute the result in a port.

HTH,
Rainer
Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Mark Brethen-2
In reply to this post by Mark Brethen-2
The following line worked,

system -W ${worksrcpath}_SHARED \
            "ld -dynamic -dylib -force_load spooles.a -r -x -o libspooles.1.dylib -install_name ${prefix}/lib/libspooles.1.dylib”

There was a warning in the main.log:

:debug:build system -W /opt/local/var/macports/build/_Users_marbre_ports_math_spooles/spooles/work/spooles.2.2_SHARED: ld -dynamic -dylib -force_load spooles.a -r -x -o libspooles.1.dylib -install_name /opt/local/lib/libspooles.1.dylib
:info:build ld: warning: -arch not specified

So I specified -arch ${os.arch} then it warned about spooles.a being i386, not x86_64. Why am I getting the warning?


Mark Brethen
[hidden email]



> On Nov 18, 2018, at 1:36 PM, Mark Brethen <[hidden email]> wrote:
>
> The spooles src creates a static ‘spooles.a’ library. I want to get a dynamic library out of it. In BSD, for a .so library you would use:
>
> ld -Bshareable -o libspooles.so.1 -x -soname libspooles.so.1 --whole-archive spooles.a
>
> For macports I tried
>
> system -W ${worksrcpath}_SHARED ld -dylib -force_load spooles.a -o libspooles.1.dylib
>
> ld fails with an error:
>
> :info:build ld: symbol(s) not found for inferred architecture x86_64
> :info:build Command failed: ld -dylib -force_load spooles.a -o libspooles.1.dylib
> :info:build Exit code: 1
> :error:build Failed to build spooles: command execution failed
>
> How do I have to modify above command so I will get the desired result?
>
>
> Mark Brethen
> [hidden email]
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Joshua Root-8
On 2018-11-19 09:05 , Mark Brethen wrote:

> The following line worked,
>
> system -W ${worksrcpath}_SHARED \
>             "ld -dynamic -dylib -force_load spooles.a -r -x -o libspooles.1.dylib -install_name ${prefix}/lib/libspooles.1.dylib”
>
> There was a warning in the main.log:
>
> :debug:build system -W /opt/local/var/macports/build/_Users_marbre_ports_math_spooles/spooles/work/spooles.2.2_SHARED: ld -dynamic -dylib -force_load spooles.a -r -x -o libspooles.1.dylib -install_name /opt/local/lib/libspooles.1.dylib
> :info:build ld: warning: -arch not specified
>
> So I specified -arch ${os.arch} then it warned about spooles.a being i386, not x86_64. Why am I getting the warning?

Because os.arch is not necessarily the same as build_arch (or
universal_archs). The former matches what `uname -p` prints, the latter
are what MacPorts has been asked to build. The flags you should use are
in configure.ld_archflags or configure.universal_ldflags depending on
whether a universal variant is being used.

- Josh
Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Mark Brethen-2
This port does not have a configure phase and I set 'universal no’ It errors with ‘-arch ${configure.ld_archflags}’. How is this variable set? 


Mark Brethen



On Nov 18, 2018, at 4:16 PM, Joshua Root <[hidden email]> wrote:

configure.ld_archflags

Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Mark Brethen-2
‘build_arch’ worked perfect, thanks Josh!


Mark Brethen



On Nov 18, 2018, at 4:34 PM, Mark Brethen <[hidden email]> wrote:

This port does not have a configure phase and I set 'universal no’ It errors with ‘-arch ${configure.ld_archflags}’. How is this variable set? 


Mark Brethen



On Nov 18, 2018, at 4:16 PM, Joshua Root <[hidden email]> wrote:

configure.ld_archflags


Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Joshua Root-8
In reply to this post by Mark Brethen-2
The default value of configure.ld_archflags is '-arch
${configure.build_arch}' provided the selected compiler supports -arch.
So ‘-arch ${configure.ld_archflags}’ expands to e.g. ‘-arch -arch
x86_64’. Don't do that. :)

You can easily find out the value of any variable in a portfile by
adding a line like:

puts "somevar = ${somevar}"

(Just run something like 'port info' to trigger it.)

- Josh

On 2018-11-19 09:34 , Mark Brethen wrote:

> This port does not have a configure phase and I set 'universal no’ It
> errors with ‘-arch ${configure.ld_archflags}’. How is this variable set? 
>
>
> Mark Brethen
> [hidden email] <mailto:[hidden email]>
>
>
>
>> On Nov 18, 2018, at 4:16 PM, Joshua Root <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> configure.ld_archflags
>
Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Mark Brethen-2
With the ‘-r’ option on ld I ended up with an object, not dylib:

brethen-air:~ marbre$ otool -hv /opt/local/lib/libspooles.1.dylib
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      OBJECT     4        688 SUBSECTIONS_VIA_SYMBOLS

Removing that, however, causes it to fail: symbol(s) not found for architecture x86_64

This builds the archive file:

:debug:build system -W /opt/local/var/macports/build/_Users_marbre_ports_math_spooles/spooles/work/spooles.2.2_SHARED/MPI/src: /usr/bin/make -f makeGlobalLib
:info:build /opt/local/bin/mpicc-mpich-mp -c -Os -fPIC -I/opt/local/include/mpich-mp aggListMPI.c -o MPI_aggListMPI.o
.
.
.
:info:build /opt/local/bin/mpicc-mpich-mp -c -Os -fPIC -I/opt/local/include/mpich-mp utilities.c -o MPI_utilities.o
:info:build ar rv ../../spooles.a MPI_*.o
:info:build ar: creating archive ../../spooles.a
.
.
.
:info:build rm -f MPI_*.o
:info:build ranlib ../../spooles.a

Then use linker to convert static library to dylib:

:debug:build system -W /opt/local/var/macports/build/_Users_marbre_ports_math_spooles/spooles/work/spooles.2.2_SHARED: ld -dylib -arch x86_64 -all_load spooles.a -x -install_name /opt/local/lib/libspooles.1.dylib -o libspooles.1.dylib

Why doesn’t this work?


Mark Brethen
[hidden email]



> On Nov 18, 2018, at 5:54 PM, Joshua Root <[hidden email]> wrote:
>
> The default value of configure.ld_archflags is '-arch
> ${configure.build_arch}' provided the selected compiler supports -arch.
> So ‘-arch ${configure.ld_archflags}’ expands to e.g. ‘-arch -arch
> x86_64’. Don't do that. :)
>
> You can easily find out the value of any variable in a portfile by
> adding a line like:
>
> puts "somevar = ${somevar}"
>
> (Just run something like 'port info' to trigger it.)
>
> - Josh
>
> On 2018-11-19 09:34 , Mark Brethen wrote:
>> This port does not have a configure phase and I set 'universal no’ It
>> errors with ‘-arch ${configure.ld_archflags}’. How is this variable set?
>>
>>
>> Mark Brethen
>> [hidden email] <mailto:[hidden email]>
>>
>>
>>
>>> On Nov 18, 2018, at 4:16 PM, Joshua Root <[hidden email]
>>> <mailto:[hidden email]>> wrote:
>>>
>>> configure.ld_archflags
>>


main.log (220K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: convert a static library to a dynamic one?

Mark Brethen-2
I think it may have been the unused objects from mpich that was causing the error, so I went back and read the ld manual again and noted that -noall_load is the default. (If you use it, you get an error message: ld: warning: option -noall_load is obsolete and being ignored). Here is the linker command that actually works:

system -W ${worksrcpath}_SHARED \
        "ld spooles.a -dylib -macosx_version_min ${os.version} ${configure.ld_archflags} -x -install_name ${prefix}/lib/libspooles.1.dylib -o libspooles.1.dylib”

brethen-air:~ marbre$ otool -hv /opt/local/lib/libspooles.1.dylib
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    11        528   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS

The dylib is actually quite small, ~4 KB, compared to the static library, 156 KB.

Mark Brethen
[hidden email]



> On Nov 19, 2018, at 1:23 AM, Mark Brethen <[hidden email]> wrote:
>
> With the ‘-r’ option on ld I ended up with an object, not dylib:
>
> brethen-air:~ marbre$ otool -hv /opt/local/lib/libspooles.1.dylib
> Mach header
>      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
> MH_MAGIC_64  X86_64        ALL  0x00      OBJECT     4        688 SUBSECTIONS_VIA_SYMBOLS
>
> Removing that, however, causes it to fail: symbol(s) not found for architecture x86_64
>
> This builds the archive file:
>
> :debug:build system -W /opt/local/var/macports/build/_Users_marbre_ports_math_spooles/spooles/work/spooles.2.2_SHARED/MPI/src: /usr/bin/make -f makeGlobalLib
> :info:build /opt/local/bin/mpicc-mpich-mp -c -Os -fPIC -I/opt/local/include/mpich-mp aggListMPI.c -o MPI_aggListMPI.o
> .
> .
> .
> :info:build /opt/local/bin/mpicc-mpich-mp -c -Os -fPIC -I/opt/local/include/mpich-mp utilities.c -o MPI_utilities.o
> :info:build ar rv ../../spooles.a MPI_*.o
> :info:build ar: creating archive ../../spooles.a
> .
> .
> .
> :info:build rm -f MPI_*.o
> :info:build ranlib ../../spooles.a
>
> Then use linker to convert static library to dylib:
>
> :debug:build system -W /opt/local/var/macports/build/_Users_marbre_ports_math_spooles/spooles/work/spooles.2.2_SHARED: ld -dylib -arch x86_64 -all_load spooles.a -x -install_name /opt/local/lib/libspooles.1.dylib -o libspooles.1.dylib
>
> Why doesn’t this work?
> <main.log>
> Mark Brethen
> [hidden email]
>
>
>
>> On Nov 18, 2018, at 5:54 PM, Joshua Root <[hidden email]> wrote:
>>
>> The default value of configure.ld_archflags is '-arch
>> ${configure.build_arch}' provided the selected compiler supports -arch.
>> So ‘-arch ${configure.ld_archflags}’ expands to e.g. ‘-arch -arch
>> x86_64’. Don't do that. :)
>>
>> You can easily find out the value of any variable in a portfile by
>> adding a line like:
>>
>> puts "somevar = ${somevar}"
>>
>> (Just run something like 'port info' to trigger it.)
>>
>> - Josh
>>
>> On 2018-11-19 09:34 , Mark Brethen wrote:
>>> This port does not have a configure phase and I set 'universal no’ It
>>> errors with ‘-arch ${configure.ld_archflags}’. How is this variable set?
>>>
>>>
>>> Mark Brethen
>>> [hidden email] <mailto:[hidden email]>
>>>
>>>
>>>
>>>> On Nov 18, 2018, at 4:16 PM, Joshua Root <[hidden email]
>>>> <mailto:[hidden email]>> wrote:
>>>>
>>>> configure.ld_archflags
>>>
>