库中的代码可以位于特定地址吗?
Posted
技术标签:
【中文标题】库中的代码可以位于特定地址吗?【英文标题】:Can code in library be located at a specific address? 【发布时间】:2019-12-06 04:22:06 【问题描述】:我正在开发一个 cmake C/C++ 嵌入式项目。我有一个跨平台的应用程序。它将在基于 PC 的模拟器以及嵌入式 (STM32) 目标上运行。一个通用的硬件抽象层允许这样做。
理想情况下,我想为目标特定的 HAL 创建一个库,例如一个在为 STM32 编译时构建,另一个在为 PC 编译时构建)。这将链接到应用程序。虽然我并不真正需要它成为一个单独的库。
我卡住的地方是 STM32 的 HAL 库包含 STM32 的启动代码 (asm)。构建并链接 HAL 库后,启动代码就会消失。我可以直接在应用程序中包含启动代码,并且它已正确链接和定位,但现在如果为 STM32 构建,我需要在应用程序中包含该文件的特殊情况。
项目文件夹结构如下:
- TheProject
- Applications
- TheMainApplication
ApplicationSource.c
CMakeLists.txt (add_executable, add sources, link HAL library)
- HAL
- Embedded
- STM32
STM32SpecificCode.c
STM32StartupCode.s
CMakeLists.txt (add_library(STM32) target_sources(*.c, *.s))
- PC
- PC Specific
CMakeLists.txt (add_library(HAL) if(STM32) add_subdirectory(STM32) link STM32 library else if PC ...)
CMakeLists.txt (project(myproj) add_subdirectory(HAL) add_subdirectory(Applications/TheMainApplication) )
实际上,目标和选项的组合比我在这里提到的要多,但为了保持简单,例如起见。
可能是我缺乏关于如何使用子文件夹的 cmake 知识,这对我来说很难,或者是项目结构不好!我非常感谢有关如何构造它的一些建议或反馈,以便 STM32 特定文件保留在 STM32 代码中,并尽可能避免应用程序 makefile 中的特殊情况。或任何其他相关建议。
谢谢
【问题讨论】:
哪种语言,C 或 C++(你有两个标签)?它们是不同的语言。 C++ 语言允许您重载函数和方法。许多编译器在与库和其他模块(目标文件)链接时可能会执行 name mangling。 您的链接器指令文件在哪里?许多嵌入式系统的链接器允许您定义 segments 并将文件或库分配给该段。您还可以为段分配固定地址。否则无法保证代码的顺序(每次编译时地址可能不同)。 包含链接器文件或至少包含您使用它的方式。正在使用什么工具链?我假设 gcc。 CMake 不进行编译或链接。 在链接描述文件中的特定地址处创建一个部分,用于放置库的.o
文件。
@ThomasMatthews 感谢您的评论,该项目在需要时使用适当的“外部 C”接口在所有地方使用 C 和 C++。在这个特定的例子中,HAL 库有一个基本的 C 接口。链接器文件位于 STM 32 代码文件夹中,但在主 CMakeLists.txt 文件中提供给链接器。抱歉,我知道这个示例缺少所有细节,但我尽量保持简单。
【参考方案1】:
将诸如 ARM 向量表之类的东西分配给特定地址确实是通过 gcc 样式工具链上的链接器部分完成的,正如一些在 cmets 中提到的那样。所需的链接器部分在源代码中使用指令进行标记,然后该部分针对链接器脚本中的特定区域。
链接器脚本几乎总是唯一的目标。即使他们不是,理论上他们分配一个未被任何代码使用的部分的位置也不是问题。
回到您真正想要弄清楚的问题上,生成本机可执行文件的构建系统总是必须包含目标唯一部分。不同的工具链和目标需要不同的标志和输入。您几乎总是需要在所使用的源文件集上有所不同。
所以通常你要做的就是组织你的构建系统,将所有目标共有的功能源以及它们的公共依赖项分组。
然后,您可以为每个目标分配一个部分,该部分提取公共源,添加目标唯一的部分,例如从源构建的 I/O 例程(或模拟),并提供适当的构建规则。最后一部分是传递适当的标志、要链接的预构建库以及指定链接器脚本的使用位置。
【讨论】:
感谢您的回答。在重新阅读我的问题(我上周五晚上匆忙写的!)之后,我意识到我实际上问了两个不同的问题。一篇是关于项目结构的,一篇是关于为什么编译到库中时启动代码没有正确定位的原因!以上是关于库中的代码可以位于特定地址吗?的主要内容,如果未能解决你的问题,请参考以下文章
Jenkins:如果我们在两个不同的 GitLab 存储库中有代码,我们可以进行“持续集成”吗?