This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F280049C-Q1: Combining Libraries with Archiver

Part Number: TMS320F280049C-Q1

SW Team,

I'm trying to put together a library I can hand to people so they can write custom code for my device.  To this end, I've put together a library project which just compiles all the sources from my main application project and builds a lib instead of an executable.  My problem comes when I try to use the library in a test project.  The linker is complaining about missing symbols, even though I believe I've properly included them in the library.  Is there a limitation on the things I can include in an archive?  I didn't see anything in the assembly language tools guide in the archiver section that would suggest this wouldn't work.

**** Build of configuration Debug for project Sygnal-MCM-Library ****

/Applications/ti/ccs1200/ccs/utils/bin/gmake -k -j 15 all -O 
 
Building target: "Sygnal-MCM-Library.lib"
Invoking: C2000 Archiver
"/Applications/ti/ccs1200/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/bin/ar2000" r "Sygnal-MCM-Library.lib" "./device.obj" "./f28004x_codestartbranch.obj" "./f28004x_globalvariabledefs.obj" "./main.obj" "./application/mcm-binaryconfig.obj" "./application/mcm-canproc.obj" "./application/mcm-cla.obj" "./application/mcm-closedloop.obj" "./application/mcm-commissioning.obj" "./application/mcm-config.obj" "./application/mcm-control.obj" "./application/mcm-factory.obj" "./application/mcm-fault-behavior.obj" "./application/mcm-fault.obj" "./application/mcm-heartbeat.obj" "./application/mcm-ifcontrol.obj" "./application/mcm-init.obj" "./application/mcm-inputctrl.obj" "./application/mcm-intercom.obj" "./application/mcm-main.obj" "./application/mcm-missing-signal.obj" "./application/mcm-outputctrl.obj" "./application/mcm-override-filters.obj" "./application/mcm-override.obj" "./application/mcm-report.obj" "./application/mcm-state.obj" "./application/mcm-task.obj" "./application/mcm-vehicledata.obj" "./application/mcm-virt-ifcontrol.obj" "./can_protocol/cascade.obj" "./can_protocol/closedloop.obj" "./can_protocol/commissioning.obj" "./can_protocol/config.obj" "./can_protocol/control.obj" "./can_protocol/error.obj" "./can_protocol/fail-op1.obj" "./can_protocol/fail-op2.obj" "./can_protocol/fault.obj" "./can_protocol/heartbeat.obj" "./can_protocol/i15765app.obj" "./can_protocol/ident.obj" "./can_protocol/kar-tech.obj" "./can_protocol/mcmglobal.obj" "./can_protocol/nlpid.obj" "./can_protocol/oscc.obj" "./can_protocol/override.obj" "./can_protocol/pid.obj" "./can_protocol/relay.obj" "./can_protocol/report.obj" "./can_protocol/signal.obj" "./can_protocol/sygnalglobal.obj" "./can_protocol/sygnalstatic.obj" "./can_protocol/vehicledata.obj" "./can_protocol/virt-if.obj" "./cla/mcm-cla-tasks.obj" "./control/DCL_PID_C4.obj" "./control/DCL_clamp_C1.obj" "./control/DCL_error.obj" "./driverlib/adc.obj" "./driverlib/asysctl.obj" "./driverlib/can.obj" "./driverlib/cla.obj" "./driverlib/clapromcrc.obj" "./driverlib/clb.obj" "./driverlib/cmpss.obj" "./driverlib/cputimer.obj" "./driverlib/dac.obj" "./driverlib/dcc.obj" "./driverlib/dcsm.obj" "./driverlib/dma.obj" "./driverlib/ecap.obj" "./driverlib/epwm.obj" "./driverlib/eqep.obj" "./driverlib/flash.obj" "./driverlib/fsi.obj" "./driverlib/gpio.obj" "./driverlib/hrcap.obj" "./driverlib/hrpwm.obj" "./driverlib/i2c.obj" "./driverlib/interrupt.obj" "./driverlib/lin.obj" "./driverlib/memcfg.obj" "./driverlib/pga.obj" "./driverlib/pmbus.obj" "./driverlib/sci.obj" "./driverlib/sdfm.obj" "./driverlib/spi.obj" "./driverlib/sysctl.obj" "./driverlib/version.obj" "./driverlib/xbar.obj" "./drivers/mcm-analog.obj" "./drivers/mcm-dac.obj" "./drivers/mcm-ecap.obj" "./drivers/mcm-gpio.obj" "./drivers/mcm-inputxbar.obj" "./drivers/mcm-pwm.obj" "./drivers/mcm-spi.obj" "./drivers/mcm-syscontrol.obj" "./drivers/mcm-watchdog.obj" "./drivers/mcm-xint.obj" "./sygnal_drivers/can.obj" "./sygnal_drivers/eeprom.obj" "./sygnal_drivers/i2c.obj" "./sygnal_drivers/timers.obj" "./sygnal_drivers/uart.obj" "./sygnal_utilities/RingBuf.obj" "./sygnal_utilities/bootloader-symbols.obj" "./sygnal_utilities/data_extractor.obj" "./sygnal_utilities/i15765.obj" "./sygnal_utilities/uart_debug.obj" "./sygnal_utilities/uds_tx.obj" "./utilities/crc.obj" "./virt_if_drivers/virtif-kartech.obj" "/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/common/f28004x/floatingptdsp/lib/c28x_fpu_dsp_library.lib" "/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/common/f28004x/vcu0/lib/c28x_vcu0_library_fpu32.lib" "/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/common/f28004x/device_support/f28004x/headers/cmd/f28004x_headers_nonbios.cmd" 

  ==>  new archive 'Sygnal-MCM-Library.lib'
  ==>  building archive 'Sygnal-MCM-Library.lib'
Finished building target: "Sygnal-MCM-Library.lib"
 

**** Build Finished ****

Toward the end of the console dump, you'll see I'm archiving:

"/Firmware/common/f28004x/floatingptdsp/lib/c28x_fpu_dsp_library.lib"

"/Firmware/common/f28004x/vcu0/lib/c28x_vcu0_library_fpu32.lib"

But then when I use the lib the archiver spits out I get this from the linker:

undefined       first referenced                                                                                                              
  symbol             in file                                                                                                                   
 ---------       ----------------                                                                                                              
 _FIR_f32_calc   /Firmware/Sygnal-MCM-Library/Debug/Sygnal-MCM-Library.lib<mcm-override-filters.obj>
 _FIR_f32_init   /Firmware/Sygnal-MCM-Library/Debug/Sygnal-MCM-Library.lib<mcm-override-filters.obj>
 _getCRC16P1_vcu /Firmware/Sygnal-MCM-Library/Debug/Sygnal-MCM-Library.lib<mcm-config.obj>          
 _getCRC8_vcu    /Firmware/Sygnal-MCM-Library/Debug/Sygnal-MCM-Library.lib<crc.obj>                 
 

Any ideas?  I will try using the t option of ar2000 to see what it says about symbols in the lib.

Thanks,

Trey

  • The plot thickens....

    The archiver says it included the libs:

    ./ar2000 t Sygnal-MCM-Library.lib 
    ...
           728   Thu Dec  8 16:54:59 2022    c28x_fpu_dsp_library.lib
         56704   Thu Dec  8 16:54:59 2022    c28x_vcu0_library_fpu32.lib

    AND the name utility says the supposedly missing symbols are present:

    ./nm2000 Sygnal-MCM-Library.lib 
    ...
    00000000 t .text:_MCM_overrideFilterInit
    00000000 U _FIR_f32_calc
    00000000 U _FIR_f32_init
    00000000 U _MCM_configGetMCMGlobal
    ...
    00000000 U _eepromWritePages
    00000000 U _getCRC16P1_vcu
    00000000 U _i2cGetState
    ...
    00000000 T _CRC_calcCrc8
    00000000 U _getCRC8_vcu
    0000002f t $C$L1

    Digging even deeper by turning on the -L option, I find that all of these symbols in question have a "UNDEFINED_EXTERNAL" section name:

    [59]    |0x00000000|C_EXT   |UNDEFINED EXTERNAL |_FIR_f32_calc
    [55]    |0x00000000|C_EXT   |UNDEFINED EXTERNAL |_FIR_f32_init

    Any ideas?  This feels similar to like a C/C++ name conflict, but clearly the symbol names are there in the archive.

  • Trey,

    We are reaching out to compiler team to help on this. Please expect response by later today.

    Regards, Santosh

  • A library only supplies the symbols for the object files that are members of the library.  It does not supply the symbols for the libraries that are members of the library.  Another way to think of it ... A library does not support any hierarchy; you cannot have a library that contains a library.  This is the case even though ar2000 allows you to specify a library as an input.  In your specific case, the file c28x_fpu_dsp_library.lib is a member of the library Sygnal-MCM-Library.lib, but there is no way for the linker to know about any symbols that are supplied in c28x_fpu_dsp_library.lib.  

    When you create library, collect together the functions (sometimes data, but that's much less common) which work together to provide a service to the user.  Supply one or more header files which declare those functions, and any data types (structures, arrays, etc.) those functions use.  Thus, it is not typical to ...

    just compiles all the sources from my main application project and builds a lib instead of an executable

    The nm2000 command shows that the function _FIR_f32_calc is called by code in the library Sygnal-MCM-Library.lib.  But it does not supply a definition of that function.  That function is probably defined in c28x_fpu_dsp_library.lib, or one of the other libraries which are currently members of Sygnal-MCM-Library.lib.

    Thanks and regards,

    -George

  • George,

    Thank you for that excellent explanation.  Based on my understanding, there are two paths to get to a single lib that has all the symbol information.

    1) Add all the sources from the dependent libraries and compile them with the main library source.

    2) Use the x option in the archiver to dump all the object files from the dependent libraries.  Then add each dumped object file to the main library using the a option of ar2000.

    Is my understanding correct?

    Thanks!

    Trey

  • George,

    I'm attempting to go down path number 2 that I outlined in the previous post, but am still running into some trouble.  I've been able to successfully extract the object files from the libs, but when I go to combine them with the lib that the project builds, the archiver tells me the object file has a corrupt member header:

    /Applications/ti/ccs1200/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/bin/ar2000 x /Firmware/Sygnal-MCM-Library/../common/f28004x/floatingptdsp/lib/c28x_fpu_dsp_library_coff.lib
     
    Building target: "Sygnal-MCM-Library.lib"
    Invoking: C2000 Archiver
    "/Applications/ti/ccs1200/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/bin/ar2000" r "Sygnal-MCM-Library.lib" "./device.obj" "./f28004x_codestartbranch.obj" "./f28004x_globalvariabledefs.obj" "./main.obj" "./application/mcm-binaryconfig.obj" "./application/mcm-canproc.obj" "./application/mcm-cla.obj" "./application/mcm-closedloop.obj" "./application/mcm-commissioning.obj" "./application/mcm-config.obj" "./application/mcm-control.obj" "./application/mcm-factory.obj" "./application/mcm-fault-behavior.obj" "./application/mcm-fault.obj" "./application/mcm-heartbeat.obj" "./application/mcm-ifcontrol.obj" "./application/mcm-init.obj" "./application/mcm-inputctrl.obj" "./application/mcm-intercom.obj" "./application/mcm-main.obj" "./application/mcm-missing-signal.obj" "./application/mcm-outputctrl.obj" "./application/mcm-override-filters.obj" "./application/mcm-override.obj" "./application/mcm-report.obj" "./application/mcm-state.obj" "./application/mcm-task.obj" "./application/mcm-vehicledata.obj" "./application/mcm-virt-ifcontrol.obj" "./can_protocol/cascade.obj" "./can_protocol/closedloop.obj" "./can_protocol/commissioning.obj" "./can_protocol/config.obj" "./can_protocol/control.obj" "./can_protocol/error.obj" "./can_protocol/fail-op1.obj" "./can_protocol/fail-op2.obj" "./can_protocol/fault.obj" "./can_protocol/heartbeat.obj" "./can_protocol/i15765app.obj" "./can_protocol/ident.obj" "./can_protocol/kar-tech.obj" "./can_protocol/mcmglobal.obj" "./can_protocol/nlpid.obj" "./can_protocol/oscc.obj" "./can_protocol/override.obj" "./can_protocol/pid.obj" "./can_protocol/relay.obj" "./can_protocol/report.obj" "./can_protocol/signal.obj" "./can_protocol/sygnalglobal.obj" "./can_protocol/sygnalstatic.obj" "./can_protocol/vehicledata.obj" "./can_protocol/virt-if.obj" "./cla/mcm-cla-tasks.obj" "./control/DCL_PID_C4.obj" "./control/DCL_clamp_C1.obj" "./control/DCL_error.obj" "./driverlib/adc.obj" "./driverlib/asysctl.obj" "./driverlib/can.obj" "./driverlib/cla.obj" "./driverlib/clapromcrc.obj" "./driverlib/clb.obj" "./driverlib/cmpss.obj" "./driverlib/cputimer.obj" "./driverlib/dac.obj" "./driverlib/dcc.obj" "./driverlib/dcsm.obj" "./driverlib/dma.obj" "./driverlib/ecap.obj" "./driverlib/epwm.obj" "./driverlib/eqep.obj" "./driverlib/flash.obj" "./driverlib/fsi.obj" "./driverlib/gpio.obj" "./driverlib/hrcap.obj" "./driverlib/hrpwm.obj" "./driverlib/i2c.obj" "./driverlib/interrupt.obj" "./driverlib/lin.obj" "./driverlib/memcfg.obj" "./driverlib/pga.obj" "./driverlib/pmbus.obj" "./driverlib/sci.obj" "./driverlib/sdfm.obj" "./driverlib/spi.obj" "./driverlib/sysctl.obj" "./driverlib/version.obj" "./driverlib/xbar.obj" "./drivers/mcm-analog.obj" "./drivers/mcm-dac.obj" "./drivers/mcm-ecap.obj" "./drivers/mcm-gpio.obj" "./drivers/mcm-inputxbar.obj" "./drivers/mcm-pwm.obj" "./drivers/mcm-spi.obj" "./drivers/mcm-syscontrol.obj" "./drivers/mcm-watchdog.obj" "./drivers/mcm-xint.obj" "./sygnal_drivers/can.obj" "./sygnal_drivers/eeprom.obj" "./sygnal_drivers/i2c.obj" "./sygnal_drivers/timers.obj" "./sygnal_drivers/uart.obj" "./sygnal_utilities/RingBuf.obj" "./sygnal_utilities/bootloader-symbols.obj" "./sygnal_utilities/data_extractor.obj" "./sygnal_utilities/i15765.obj" "./sygnal_utilities/uart_debug.obj" "./sygnal_utilities/uds_tx.obj" "./utilities/crc.obj" "./virt_if_drivers/virtif-kartech.obj" "/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/common/f28004x/floatingptdsp/lib/c28x_fpu_dsp_library.lib" "/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/common/f28004x/vcu0/lib/c28x_vcu0_library_fpu32.lib" 
      ==>  new archive 'Sygnal-MCM-Library.lib'
      ==>  building archive 'Sygnal-MCM-Library.lib'
    Finished building target: "Sygnal-MCM-Library.lib"
     
    /Applications/ti/ccs1200/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/bin/ar2000 r  ./FIR_f32.obj
    makefile:297: recipe for target 'post-build' failed
      -->  error: Corrupt member header: './FIR_f32.obj'
    gmake[2]: [post-build] Error 1 (ignored)

    It seems to me this should work.  I was originally using the index library c2k supplies and wasn't getting any object files out.  Then I switched to using their coff format lib (my project is coff) and started to get the object files from dump from the archiver.  I just can't seem to combine the two.  This should work right?  I'm currently on 22.6.0 LTS.

    Trey

  • I'm trying to put together a library I can hand to people so they can write custom code for my device.

    Why must it be a single library?  It is very common for a single project to link with multiple libraries.

    The command ...

    ar2000 r  ./FIR_f32.obj

    ... is not valid.   A library name is expected.

    ar2000 r  name_here.lib ./FIR_f32.obj
     

    Thanks and regards,

    -George

  • Its a user experience thing.  I want to hand my customers the simplest possible package, so to that end I want to combine all the object into a single lib.

    Also thanks for noticing the file name boo boo.  I had used the ${output} macro as is done in the main archiver properties, but clearly there is no defined ${output} for post build steps.  I set the filename manually and its working and progress is being made.

    Thanks for pointing me in the right direction George!