Author Topic: STM Cube: distributing a project where not all modules are supplied in .c source  (Read 4624 times)

0 Members and 1 Guest are viewing this topic.

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
32F417

The way Cube normally works is that the source code tree is compiled into .o files into the DEBUG directory. This directory is totally cleaned out beforehand with
rm *.* or some such.

There is also a RELEASE directory but the distinction is purely artificial; you can build everything in DEBUG and just change the optimisation level under project properties.

I want to set it up so some people can develop code but I don't want to give them all the .c sources.

There is a whole load of complicated ways to do this. Perhaps the neatest is to wrap up all the .o files into a library (.a), but the script for that is not trivial. And it doesn't actually give you anything because anybody can list the library and get the .o modules. And you still have to distribute .h files etc. So you just create a lot of work for yourself.

I was thinking of simply deleting the applicable .c files, collecting up their corresponding .o files and saving them somewhere, and adding a path to the linker command line where the linker can look for .o modules.

I wonder if there is some neater way. Unfortunately Cube is a vast labyrinth of scripts and every time you install a new version you overwrite these. So this needs to be something which can run as a standalone batch file. I could even run that as a post build step in the primary project; I already have stuff in there to e.g. add a crc32 to the binary output file.
« Last Edit: March 05, 2023, 05:27:27 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline GromBeestje

  • Frequent Contributor
  • **
  • Posts: 294
  • Country: nl
I assume you mean the IDE with Cube. This uses afaik the eclipse build system. I am not that familiar with it.
The standard way to do what you indent is indeed to create an .a file.

I am working with a bunch of Makefiles myself, and I have created a way to create such libraries. You'll have to supply the corresponding .h files for the functions yourself.

The way I create a static library from my environment is like

See for example https://github.com/a-v-s/ucdev/blob/master/build/staticlib/rtt/Makefile

You have to set your target architecture. Eg. An STM32F0 series is a Cortex-M0,  STM32F1 series is a Cortex-M3, etc.
Code: [Select]
ARCH?=ARM
SUBARCH?=M3

Other then that, you add your source files and include directories required to build the library.
Code: [Select]
C_SOURCES  += $(RTT_DIR)/RTT/SEGGER_RTT.c
C_SOURCES  += $(RTT_DIR)/RTT/SEGGER_RTT_printf.c
C_INCLUDES += $(RTT_DIR)/RTT
C_INCLUDES += $(RTT_DIR)/Config

Please note, the header files required so *use* the library can be less then the ones you need to *build* it.

The makefiles assume the cross compiler is in the path, and for arm is prefixed by arm-none-eabi-
This can be overriden by defining PREFIX, etc one can set [code[PREFIX=/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/arm-none-eabi-[/code]

I am not that at home in the eclipse build system, or what modifications the Cube IDE has wrt standard Eclipse, but it should have some place in the build configuration where you can specify libraries, where you specify the library. It will have a path and a library name (without the lib prefix and without the .a suffix)

In the raw makefile, you'd do
So, when you got your .a file
/some/path/to/library/libexample.a
you add the linker flags,
Code: [Select]
-L /some/path/to/library -l example
 

Offline artag

  • Super Contributor
  • ***
  • Posts: 1344
  • Country: gb
I don't see why distributing a bunch of .o files is any different from a .a file (except it's less convenient for the user). A .a file is literally a bunch of .o files in one. It only differs from a tar or zip file in that the linker expects only .o files and can search them for the references they contain exactly as it does .o files. In a link script the difference is primarily that specified .o files will always be included whilst only those matching link references will be pulled from the .a file and included in the build.

If your aim is to obscure the names of functions .. you can't really do that and allow the end user to do a link. It's what a link needs.

I guess you could be trying to expose the API but not the internal parts of the build. In that case you could consider providing the API via a jump table and a separate binary. The jump table has the only symbols visible and implements some sort of bridge to the actual binary. I think a number of devices with soft fuinctionality such as the espressif chips, Nordic nrf51/52 and cypress ezusb-3 do this. It's a lot more maintenance for you though.

Another possibilty is to use  meaningless internal function names, perhaps supported by #defines so that it's not completely unmaintainable. To be honest, in this age of open source, it feels like you're just creating extra work and making your offering less attractive to customers.
 
« Last Edit: March 05, 2023, 10:34:01 am by artag »
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
Thanks all.

Let me fill in more detail.

I have a Cube IDE project which comprises of

- some ex Cube MX (the STM "code generator") code, largely modded to remove bloat; the project was started years ago with this bit
- ST port of FreeRTOS (very few mods were needed)
- ST port of LWIP (lots of mods were needed)
- ST port of MbedTLS (lots of mods were needed)
- ST ETH code (loads of mods again)
- ST USB code (client only - CDC & MSC) (load of mods needed)
- ST port of FatFS (very few mods)
- interface code for SPI serial FLASH
- interface code for a number of serial ports
- a couple of LWIP-interfaced modules written by outside people (no doubt they will recognise this ;) )
- a ton of code I wrote over the past 2 years of my life; stuff which defines what the product actually is, an API for a ton of stuff, and countless bug fixes to stuff above, revealed in extensive 24/7 testing

The project is in a directory tree:



and since I didn't set up the ST port stuff, I don't know where and how these directories are set up, but I don't need to know. I know how the stuff I've been writing last 2 years works :)

I am not posting what this thing does :) but I can say that in some application contexts there will be outsiders (with C expertise) writing their own modules. They will be given the whole Cube project, with an example file like hello.c. I will absolutely not be supporting ST Cube and creating a project from scratch; that is way beyond the call of duty.

And the idea is that their life will be far easier than if they were coding for some development board (these normally come with example code but usually it is crap for anything beyond trivia) or for some "hobby board" (which tend to be mechanically unsuitable for serious industrial use, as well as production-problematic long-term). For example LWIP and proper code examples will make the development of internet applications a lot easier.

And I don't want to give them all the source code. They can have the ex-ST code (even though the fixes to make it work probably amount to a man-year) because it is basically public-domain, but I don't want to give out the whole lot, especially most of the stuff which I wrote.

These other coders will write applications which run at base+32k (0x00008000) because the bottom 32k is a boot block which has various recovery features, etc. Obviously I won't publish the boot block code, too.

So I am looking for the simplest path to generate this "0x00008000" development kit.

The main difference will be the linker script, obviously. That's easy. No boot block section, start collecting TEXT sections at 0x00008000, etc.

Then I need to delete the .c files for all the stuff I don't want to hand out. But I need to provide the .o files. I also need to provide all the .h files for the entire project and I am hoping that I can use all the existing ones as-is.

So I need to copy the .o files to another directory e.g.

<projectdir>/O_FILES

and add a linker command line option to look in there.

The stuff should be a standalone batch file. Something obvious and self documenting so in 10 years' time it will be obvious what it does.

The batch file can be run as a post build step, so the above .o files are always current.

Out of maybe 1000 .c files there would be only about 30 that would be stripped out.

I am not worried about function names being visible. I just don't want to hand out nicely commented and valuable C source in some cases :)

Have I overlooked anything?

The "neat" way would be to produce one huge .a library file, but that is just "neat" and achieves nothing, given that Cube itself is about 4000 files! And I would have to do what I think would be a vast amount of work on the .h files. Also I have no idea how one would condense all that code in that directory tree into one library, and keep the .h files right. There are multiple pairs of src and inc directories so e.g. LWIP has one pair, FatFS has another pair, and so on.

So I am looking for the simplest way to be able to remove some .c files and supply just the .o files, and this needs to survive the rm *.* cleanup command which Cube does on the Debug directory at the start of each build of a project which has been cleaned-up.
« Last Edit: March 05, 2023, 07:23:35 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 8046
  • Country: ca
  • Non-expert
Get them to sign an NDA.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
That's really funny.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline artag

  • Super Contributor
  • ***
  • Posts: 1344
  • Country: gb
That's really funny.

I'm inclined to agree.

But what is it about NDAs that makes corporate types happy ? Is it just an arse-covering thing that ensures they can tell their boss it isn't their fault the competitor knows their secrets ?
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4263
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
ARM CMSIS Maths package is distributed via .a files and linked into stm32cube no problem. That should be the way to go.
Take the files you want to hide. Compile them into an .a, link this into your project.

Then you share the workspace, you omit this project that compiles the .a, but keep the output directory that the other projects refer to.
Note that you won't be able to use the "depends on' subproject options in eclipse if you intent to remove the project.

You can even apply this method to all your other lirbaries you use, compilation time must be horrible in this project because everything recompiles all the time.
 
The following users thanked this post: thm_w

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
The recompilation is only for modules for which the "makefile generator" in Cube cannot find the .o file.

So if you do a Clean Project, you do indeed get the lot recompiled.

This means that you could give someone the whole project, having just deleted the "non-distributed" .c files, and it will work just fine. Until he does a Clean Project ;) and then he will have to restore these .o files. The rm *.* command doesn't run on every build - sorry if I suggested that.

But why would someone do a Clean Project? Well... Cube doesn't always 100% notice that some file was externally edited and just dropped into the project directory. So when I am setting up the Cube project on a new machine (using the Import function - this is easy to do wrong but easy if properly documented step by step) I always do a Clean. Or someone could do a Clean by mistake. But that isn't fatal because they will have the .o files in an archive anyway.

I am just really confused at how a Cube project gets built up. For example where the ST Port of LWIP comes from and how it gets loaded into Cube. But luckily all this has been done.
« Last Edit: March 07, 2023, 04:36:17 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16289
  • Country: fr
That's really funny.

Well, funny. Dunno about that.
From what I got, you allow your customers to write custom firmware for your products, so you need to distribute the firmware in whatever form is most convenient for you while being usable for your customers.
While NDAs are OK for B2B, you don't force end-users to sign NDAs to use a product. I guess that's what you found funny, but thm_w may not have had the whole context.

So while a NDA per se may not make much sense in your case, surely your products and associated firmware are disitributed with some kind of license agreement?
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 8046
  • Country: ca
  • Non-expert
That's really funny.

Well, funny. Dunno about that.
From what I got, you allow your customers to write custom firmware for your products, so you need to distribute the firmware in whatever form is most convenient for you while being usable for your customers.
While NDAs are OK for B2B, you don't force end-users to sign NDAs to use a product. I guess that's what you found funny, but thm_w may not have had the whole context.

So while a NDA per se may not make much sense in your case, surely your products and associated firmware are disitributed with some kind of license agreement?

Ah I didn't realize this was for end customer use, all I see in the OP is "I want to set it up so some people can develop code but I don't want to give them all the .c sources.", and I assumed it was contract work being done.

Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
It's actually a bit of each.

My point was that NDAs are worthless because if somebody wants to rip off your product they can do so and your only remedy is a $10k/day lawyer. And if you want to take action across country borders, the 10k will just be wasted.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4263
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
You know you can read up on how Cube Eclipse works, right?
You can also see the makefiles that are generated and how they fit together.
Sure Eclipse is somewhat strange, because it's a bit older.

One thing you absolutely should not be doing is working against Eclipse. It will make your job hard, and it will not align with the expectations of your customers.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
Quote
You know you can read up on how Cube Eclipse works, right?

No doubt you can, but you would need a PhD :)

This is Cube


Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline John Coloccia

  • Super Contributor
  • ***
  • Posts: 1217
  • Country: us
Curious why you want to keep the source code private? FWIW, not distributing in source form makes it much less likely that I would consider using any third party library in an embedded project.

As a side note, I've yet to see Eclipse generated makefiles that work properly, and generally speaking the way they detect/handle dependencies is atrocious...and often just flat out wrong. It's not uncommon that I'll just write my own makefile and be done with it.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
The product is a hardware one. I described what modules are in it above, and while most of these are open source (albeit many containing bug fixes) there are a few which aren't O/S. Of these, a few are quite specific to the functionality and I don't want to hand out the source code to those.

Re Cube generating wrong dependencies, I found all kinds of weird stuff when we first started using it a few years ago, but nowadays it seems to work ok, even correctly detecting which files were edited externally (which didn't used to work, despite a config option for it).

But still an easy recommendation if somebody is having trouble is to do a Clean Project. That deletes everything in the DEBUG directory, but creates the described problem that for some of the .o files will not have had a .c file supplied.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 478
  • Country: be
But still an easy recommendation if somebody is having trouble is to do a Clean Project. That deletes everything in the DEBUG directory, but creates the described problem that for some of the .o files will not have had a .c file supplied.

Then you need two projects:
  • one for yourself, building: [ *.c + *.h ] --> *.o --> secret-lib.a --> link to binary
  • another for distribution: *.h + secret-lib.a --> link to binary
This is essentially done for libc, you will find all your headers in include directory and corresponding libc.a in lib/arm-none-eabi/newlib/thumb/v7e-m+fp/hard directory (or whatever your architecture is).
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 478
  • Country: be
BTW, I always say make clean when I switch branches, or cherry-pick a commit, or merge my branch with master. Or start my day, for that matter. Consider this the normal practice.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
Quote
Then you need two projects:

Exactly!

I am just not sure how to collect stuff into a .a file. Under DEBUG I see a load of .o .d .su files.

Quote
This is essentially done for libc

I have already replaced libc.a with one which is a) weakened and b) has had the printf family removed (and I have a replacement printf which doesn't use the heap, etc - various previous threads).

Quote
I always say make clean when I switch branches, or cherry-pick a commit, or merge my branch with master. Or start my day, for that matter. Consider this the normal practice.

I concur, but during a day's development this is not needed.

It is obsolutely necessary when reverting to a previous version of a project.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 478
  • Country: be
Quote
Then you need two projects:

Exactly!

I am just not sure how to collect stuff into a .a file. Under DEBUG I see a load of .o .d .su files.

-- In your in-house project the final binary should depend on secret-lib.a .
-- This library, in turn, should depend on, and be built from, the number of .o files.
-- These particular .o files should depend on .c files that you want to keep inside.

Forget .d and .su, these are text files with dependency and stack usage information. You only need object files to create the secret-lib.a .
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: es
Google "stm32cubeide create library" returns ~101000 results, but you don't need a PhD to pick the first one  ;D
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 478
  • Country: be
One more thing.

You would want your secret-lib.a distributed without any debug information, stripped and optimized to death with -O3 or -Os. For that, you should have a separate set of CFLAGS for the sources which make up the library.

Probably, consider creating several variants of the library, and name them appropriately, for your own confidence and peace of mind, like
-- secret-O3-release.a (for external use)
-- secret-Os-release.a (the same)
-- secret-Og-debug.a (for yourself)
-- etc


Another one more thing :)

Consider creating a file with version and build information, say secret-version.c which will be included into the library. It should merely contain one line:

Code: [Select]
__attribute__((used)) static const char secret_version[] = "(@) " __SECRET_VERSION__ " built on " __DATE__ " at " __TIME__;

Then, the version can easily be had with

Code: [Select]
$ strings secret-lib.a | grep \(@\)
(@) gimbal-2.7-RC-ga865e9142-dirty built on Mar  9 2023 at 15:14:38

Supply __SECRET_VERSION__ to the CFLAGS mentioned above.
« Last Edit: March 09, 2023, 02:20:31 pm by eutectique »
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
This is brilliant stuff - thank you very much!

Before I read the above, I did a little hack to see if there is an easy way to get the linker to pick up .o files from some directory. There doesn't appear to be; this is possible only with libraries (.a). However I found this bit



where you can create a directory and put .o files in there, but you have to specify all the .o files individually. Well, I have about 20 of these "no source provided" files. Making a library would be neater - especially as an automatic post build step in Cube.

So the next step will be to use the Archiver (ar) tool to make a library e.g.

http://www.delorie.com/djgpp/v2faq/faq8_22.html

Funny you mention debug level. I am currently running with Max. But varying this makes no difference to the binary size. It sounds like it varies the symbol information loaded into the .o file - correct?



I am not actually that bothered about symbols in these files - I don't have stuff like "TOP_SECRET_RSA_KEY" in there :) I belive M$ did that once in WinNT.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: es
Seriously, the first google result contains a detailed instruction how to configure CubeIDE to produce a static library: https://community.st.com/s/question/0D53W00000HNPWISA5/writing-stm32cubeide-libraries-what-is-the-best-practice

-O3/-Os and symbol stripping are to make decompilation of your *.o back to C harder.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
Sorry, but I am too thick to understand that post :)

Looks like my best option is to knock up a batch file which collects up all the .o files (for which I am not providing the source) into a .a library, and add that library to a linker search path.

Then I need to work out how to change the compiler debug-level just for those source files. I found that - it is under Properties for each file.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 478
  • Country: be
Well, I have about 20 of these "no source provided" files. Making a library would be neater - especially as an automatic post build step in Cube.

Well, I would strongly advise on creating the library and using it for your own build. Not just a post-build step to produce a by-product. Eat your own dog food, you know :)

Yes, ar is the tool to create the library.


Quote from: peter-h
Funny you mention debug level. I am currently running with Max. But varying this makes no difference to the binary size. It sounds like it varies the symbol information loaded into the .o file - correct?

This is probably because sections debug.* are so big that the variance in the size of .text is at the noise level.


Quote from: peter-h
I am not actually that bothered about symbols in these files

Let me convince you with an example. That file with one-line version string.

Compile it without debug info, get the section headers, get the file size:

Code: [Select]
> arm-none-eabi-gcc -Os -c -o version-string.o version-string.c
> arm-none-eabi-objdump -h version-string.o

version-string.o:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000000  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000034  2**0
                  ALLOC
  3 .rodata       00000044  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      00000058  00000000  00000000  00000078  2**0
                  CONTENTS, READONLY
  5 .ARM.attributes 0000002a  00000000  00000000  000000d0  2**0
                  CONTENTS, READONLY

> ll version-string.o
-rw-rw-r-- 1  900 Mar  9 16:54 version-string.o


Now the same with debug info:

Code: [Select]
> arm-none-eabi-gcc -Os -ggdb3 -c -o version-string.o version-string.c
> arm-none-eabi-objdump -h version-string.o

version-string.o:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .group        0000000c  00000000  00000000  00000034  2**2
                  CONTENTS, READONLY, GROUP, LINK_ONCE_DISCARD
  1 .text         00000000  00000000  00000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .data         00000000  00000000  00000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          00000000  00000000  00000000  00000040  2**0
                  ALLOC
  4 .rodata       00000044  00000000  00000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .debug_info   0000005d  00000000  00000000  00000084  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
  6 .debug_abbrev 00000047  00000000  00000000  000000e1  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
  7 .debug_aranges 00000018  00000000  00000000  00000128  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
  8 .debug_macro  00000011  00000000  00000000  00000140  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
  9 .debug_macro  00000a78  00000000  00000000  00000151  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
 10 .debug_line   00000031  00000000  00000000  00000bc9  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 11 .debug_str    00002c72  00000000  00000000  00000bfa  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 12 .comment      00000058  00000000  00000000  0000386c  2**0
                  CONTENTS, READONLY
 13 .ARM.attributes 0000002a  00000000  00000000  000038c4  2**0
                  CONTENTS, READONLY

> ll version-string.o
-rw-rw-r-- 1  20K Mar  9 16:52 version-string.o


So, it's 900 bytes vs 20KiB of file size.

The actual payload is the same though, 68 bytes:

Code: [Select]
> size version-string.o
   text    data     bss     dec     hex filename
     68       0       0      68      44 version-string.o
 
The following users thanked this post: peter-h

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
This is getting interesting. Compiling a file with no debug makes it impossible to step through it with the debugger. Unless you debug in assembler (disassembly) mode, but that just shows mostly garbage.

ST built their libc.a with debug info because when I step through that (has to be in assembler mode; no source is provided) I see various function names.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 478
  • Country: be
ST built their libc.a with debug info because when I step through that (has to be in assembler mode; no source is provided) I see various function names.

That was my point exactly. With debug info, you show much more than public functions and variables of your library.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
A bit of fun with the ar @file option... took a while to work this out, and not all ar versions support it, but the ST GCC seems to.

Done it.

The AR command processes about 30 .o files into a library in well under a second, so I have put this into my Cube post build batch file.

What I have not found a way to do with a batch file is how to set up an additional linker library path etc. I am sure it is possible but Cube has thousands of files.

The resulting .a lib is 60MB and I wonder how much of that must be symbols, which are not needed. I think that to some extent one could achieve a similar result with AR to compiling the .c sources with debug level zero, but a lot of symbols must be retained otherwise a linker won't be able to do anything with it.
« Last Edit: March 09, 2023, 11:09:16 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4263
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Go make a new workspace and play around with a project that compiles to a library that you can link in another project.
Learning this takes effort, and requires reading the docs, but it's worth it.

Or you just ask chatgpt how to do it. It has read all the docs for you.

btw eclipse does a make clean every time you change project settings.

An alternative, depending on how sensitive the code is, obfuscate the code.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4602
  • Country: gb
  • Doing electronics since the 1960s...
Thank you all.

I have pretty well done it.

One of the more fun bits was how to delete a list of files where the names are supplied in a file. Obviously there are loads of ways to do that, starting with various "unix" utilities that exist for windoze, but I wanted to do it just using built-in windoze cmd commands. It was done with DEL and the FOR... looping syntax.

The AR portion was actually easy.

I found some funny stuff e.g. if you config Cube Linker options to expect a library at a certain path (and you have to specify not just the path but also a lib name then, which is odd) then that library file has to be present, but if you don't want this lib to be used (which is legitimate because during a normal build of the non-distributable version you get all the .o files, and you get them before the linker is invoked, whereas the library generated in post-build is generated after the linker is invoked) the linker fails with an error. IOW, there seems to be no way to use libraries which may or may not be present. So I had to use AR to create an empty library, by creating one with a nonexistent-file.o). It is just 1k in size. What I am doing may not be obvious, without a lot more detail.

In the end the whole job was done using about 20 lines in a .bat file which runs as a post build in Cube.

That obfuscation is funny. About 30 years ago I paid someone to write a program to do that for Pascal source. It also usefully compressed the size of the program.

« Last Edit: March 11, 2023, 09:40:03 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4438
  • Country: gb
A few topics come to fore here.  Collaboration.  IP.  Evolutionary complexity.

None of them mix well.  More over, I expect you are about to find the hard way, as I've suggested at several times, once you start with multiple developers or worse, multiple teams of developers and you introduce "business stakeholders" it get exponentially more complicated extremely quickly.

I would echo those who have said, "DO NOT FIGHT ECLIPSE".  Your choices are to abandon it or learn to make it help you.  You can hybrid the projects, we tend to run hybrids in work with independant git, java, maven and eclipse (or inteliJ) build contexts.  When you set up and maintain so many projects in Java/Eclipse/Maven this doesnt even strike one as complex.  In context of your case, this would amount of adding your own custom "parts".  I note you already have a post build factory script.

On learning eclipse, cube mx, ST Cube IDE.  It breaks down to this:

Core Eclipse + CDT C/C++ Developer toolkit plugins <-- these are best downloaded as a pre-configured bundle which deletes most of the Java stuff for you too.
Then you add on top a handful of STM plugins.  These are embedded panels and tabs in various locations throughout Eclipse customized or entirely bespoke to STM. 
Cube itself is just a stand alone application which they have embeded into Eclipse now.
The VAST majority of those multi-gb files are source code, examples and documentation.  If you were to strip those folders back to what is the actual IDE it would be about 400Mb tops, probably half that is IDE cruft too.

Eclipse itself is not that hard to learn and a lot of what you need to solve is already configurable with it or by adding plugins.  If Eclipse won't help you, add a custom Make file or Sconscript or CMake and get eclipse to call it when you hit "Build".  Hybrid approaches can have side effects and work arounds, YMMV.

Try this for example.  Go and download a Vanila C/C++ CDT Eclipse IDE.  Follow a guide to add the toolchain to it yourself!  Get it to compile HelloWorld.a and link it into HelloWorld.exe   Without all the clutter from STM32 it should help you learn a little about what is Eclipse and what it will do and what are the STM complications.
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4438
  • Country: gb
STM32CubeIDE does have a "New static library" wizard if I'm not mistaken.

On brass tacs of how you solve having different audiences for different parts of the application and keep one group out of the others way or hiding IP and knowldge.

There are no short cuts.  You have to componentise.  It might be worth thinking it through and not just taking an evolutionary retro-active step but architect it a little now to make it more flexible to carry on getting more complex and remain managable.

In day to day, eclipse will happily "relate" projects in the work space, such that the dependencies comes from the locally built copies if they exist, OR come from the precanned imports.

You share code via git.  The other parties do no have access to all repos.  In the "public" repo you put the binary releases (.a/.la/.so et. al) and headers.  In the "private" repos you put the code for the libraries.

A core developer has full source code access to all modules.  In his/her eclipse they have each "project" open in the workspace and the relevant dependencies set between them.  If they built the top layer project and there are changes in the library project, Eclipse will rebuild and locally link them.

A 3rd party developer only has the code for the bit he is working on.  For him the "common" and "library" deps have to be downloaded and installed from the public releases repo. 

Both of these can be managed in a single set of Eclipse build configs.

On your diplomatic issues and political / techno-political aspects of how different people respond to different patterns, architectures and restrictions, ... you are on your own!

I will give you one bit of advise.  If you are going to hide the code from the 3rd party developers, one of two things will happen.  Either you have written extensive documentation or they will rewrite their way around your code and do  themselves, making everything twice as complex as it's need to be.
« Last Edit: March 12, 2023, 10:56:01 am by paulca »
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf