Closed kammce closed 9 months ago
I guess what this really comes down to, "can I inject flags for test packages and remove them for non-test package builds."
If my application, with a differing binary model to the applications already pre-built libraries, can I use -bmissing
to build those dependencies and have their test packages build and properly link and also use the correct flags for my application.
My user_settings.yml should look like:
libc: [null, "custom"]
A suggested option was to use a new settings category such as "libc". Have my application opt into it by using settings = "...", "libc"
. This half way works. It works as I want with the profiles but it doesn't work for test packages. Unfortunately for test packages, the arm-gnu-toolchain can still see the global libc
setting and applies it even though the test package does not opt into that setting, meaning the default is not set and the test package fails to link.
Here is what my version of the GNU ARM toolchain package_info method looks like:
def final_libc(self):
libc = self.settings_target.get_safe("libc")
final_libc = None
self.output.info(f"libc = {libc}")
if libc:
self.output.info("libc is alive! Getting newlib!")
final_libc = self.settings_target.libc.get_safe("specs")
self.output.info(f"final_libc = {final_libc}")
return final_libc
def package_info(self):
self.cpp_info.includedirs = []
bin_folder = os.path.join(self.package_folder, "bin/bin")
self.cpp_info.bindirs = [bin_folder]
self.buildenv_info.append_path("PATH", bin_folder)
self.conf_info.define(
"tools.cmake.cmaketoolchain:system_name", "Generic")
self.conf_info.define(
"tools.cmake.cmaketoolchain:system_processor", "ARM")
self.conf_info.define("tools.build.cross_building:can_run", False)
self.conf_info.define("tools.build:compiler_executables", {
"c": "arm-none-eabi-gcc",
"cpp": "arm-none-eabi-g++",
"asm": "arm-none-eabi-as",
})
f = os.path.join(self.package_folder, "res/toolchain.cmake")
self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", f)
if self._should_inject_compiler_flags:
common_flags = self._c_and_cxx_compiler_flags
self.conf_info.append("tools.build:cflags", common_flags)
self.conf_info.append("tools.build:cxxflags", common_flags)
self.conf_info.append("tools.build:exelinkflags", common_flags)
self.output.info(f"C/C++ compiler & link flags: {common_flags}")
libc = self.final_libc()
if libc == "custom":
self.output.info("Using custom libc implementation!")
else:
STUB_LIBC = ["--specs=nano.specs", "--specs=nosys.specs"]
self.conf_info.append("tools.build:exelinkflags", STUB_LIBC)
self.output.info(f"Using newlib libc: {STUB_LIBC}")
I also added some complexity to the libc for no other reason to but to see if it would do any difference. My current users settings look like:
libc:
newlib:
specs: [null, "custom"]
After speaking with the conan team on slack, I have come to the conclusion that this is not necessary. I was mistaken that test packages got built from dependencies if the prebuilt didn't exist. Since this is not the case, the problem does not exist.
What is your question?
I'm working on https://github.com/conan-io/conan-center-index/pull/17528 and I'm not sure how to deal with test packages and applications that want to choose their libc specification.
With
arm-gnu-toolchain
for baremetal, you need an implementation for your libc. There are a couple of them out there but two of the provided compilers are the best for test packages because they get rid of the linker errors. The linker flags are--specs=nano.specs
and--specs=nosys.specs
.nano.specs
defines implementations for memcpy, printf etc andnonsys.specs
implements the lowest level C libraries for reading and writing to files and gathering memory for malloc.nosys.specs
simply defines these as calls to abort/exit. It is meant to just fill the gaps and not to be used. This is great for test packages because it allows test packages to build without issue without each test package requiring special cross compiler flags in their cmake files. But my issue is figuring out how to disable this automatic injection for their applications. Here is what I'd like the user to be able to do:The
lpc4078
profile is the target profile and contains information about the chip's architecture and os, etc. Here is what it looks like (the build type is a default for users if they want to override it):The build environment variables are for
make
,cmake
and any other build system to be used to automatically link to the correct library. Note thatcortex-m4f
is not a arch that is currently available in the conan settings but is available in my user_settings. Theplatform
option is something key to my ecosystem.The
arm-gcc-12.3
looks like this:I distribute these both so users can select their target microcontroller and their target compiler. They could
include()
them both into a single profile if they wanted to for their project.arm-gnu-toolchain
will look at the arch flag and generate compiler & linker flags for the user based on their selection. The linker flags are the issue. The reason removing these is helpful is thatnano.specs
disables exception handling which I need for the software I'm building. I'd prefer to use picolibc or potentially another libc implementation. Here are the things I've tried:Using Settings
This is what I tried. It made sense to me but the issue comes with how to affects packages. If I use this in my profile, none of my packages will have
libc
defined for them. I could recompile them for this, but the issue is that the libc type doesn't change how the binaries are generated. This setting only affects the final binary and how it is linked. So a setting for this doesn't really make sense, even though it would allow the compiler to choose correctly with a host profile.Using Options
I tried options but they were never the correct choice for the tool package. Host profile options cannot find their way to the tool package and thus are not set correctly. So to make this work I'd have to add something like this:
custom-libc
looks like this:The default is included to get info like your native compiler, native arch, etc. That way I can just append my custom option to the profile. My only issue is that its really easy to forget that last flag. And it looks really strange. Forgetting to add this build profile is a silent failure which is a problem.
Using the CLI
This works, by adding
-o:b custom_libc=True
but adds even more text for the user and is error prone. It has the same issue as using the build options flag.Using environment variables
I haven't tested this out yet but I believe it can work. I add the following to the lpc4078 profile:
This way my compiler's toolchain.cmake file can do the following:
This would work and alert the user at the very least, but still not my favorite option.
Which is the right path?
I'm not sure which is the right path so I'm asking the conan team for help here.
Have you read the CONTRIBUTING guide?