當(dāng)前位置:首頁 > 嵌入式 > 嵌入式軟件
[導(dǎo)讀]關(guān)于2.6內(nèi)核Makefile相關(guān)的文章鳳毛麟角,筆者抽時間完成了這篇分析文章,讓讀者迅速熟悉Linux最新Makefile體系,從而加深對內(nèi)核的理解。

[摘要] 由于Linux的獨特優(yōu)勢,使越來越多的企業(yè)和科研機構(gòu)把目光轉(zhuǎn)向Linux的開發(fā)和研究上。目前Linux最新的穩(wěn)定內(nèi)核版本為2.6.17,但是當(dāng)今絕大部分對于Linux Makefile的介紹文章都是基于2.4內(nèi)核的,可以說關(guān)于2.6內(nèi)核Makefile相關(guān)的文章鳳毛麟角,筆者抽時間完成了這篇分析文章,讓讀者迅速熟悉Linux最新Makefile體系,從而加深對內(nèi)核的理解,同時也希望能對Linux在公司的推廣起到一定的推動作用,算是拋磚引玉吧!

1 Makefile組織層次

Linux的Make體系由如下幾部分組成:

Ø 頂層Makefile

頂層Makefile通過讀取配置文件,遞歸編譯內(nèi)核代碼樹的相關(guān)目錄,從而產(chǎn)生兩個重要的目標(biāo)文件:vmlinux和模塊。

Ø 內(nèi)核相關(guān)Makefile

位于arch/$(ARCH) 目錄下,為頂層Makefile提供與具體硬件體協(xié)結(jié)構(gòu)相關(guān)的信息。

Ø 公共編譯規(guī)則定義文件。

包括Makefile.build 、Makefile.clean、Makefile.lib、Makefile.host等文件組成。這些文件位于scripts目錄中,定義了編譯需要的公共的規(guī)則和定義。

Ø 內(nèi)核配置文件 .config

通過調(diào)用make menuconfig或者make xconfig命令,用戶可以選擇需要的配置來生成期望的目標(biāo)文件。

Ø 其他Makefile

主要為整個Makefile體系提供各自模塊的目標(biāo)文件定義,上層Makefile根據(jù)它所定義的目標(biāo)來完成各自模塊的編譯。

2 Makefile的使用

在編譯內(nèi)核之前,用戶必須首先完成必要的配置。Linux內(nèi)核提供了數(shù)不勝數(shù)的功能,支持眾多的硬件體系結(jié)構(gòu),這就需要用戶對將要生成的內(nèi)核進行裁減。內(nèi)核提供了多種不同的工具來簡化內(nèi)核的配置,最簡單的一種是字符界面下命令行工具:

make config

這個工具會依次遍歷內(nèi)核所有的配置項,要求用戶進行逐項的選擇配置。這個工具會耗費用戶太多時間,除非萬不得以(你的編譯主機不支持其他配置工具)一般不建議使用。

用戶還可以使用利用ncurse庫編制的圖形界面工具,這就是大名鼎鼎的:

make menuconfig

相信以前對2.4內(nèi)核比較熟悉的用戶一定不會陌生。當(dāng)然在2.6內(nèi)核中提供了更漂亮和方便的基于X11的圖形配置工具:

make xconfig

當(dāng)用戶使用這個工具對Linux內(nèi)核進行配置時,界面下方會出現(xiàn)這個配置項相關(guān)的幫助信息和簡單描述,當(dāng)你對內(nèi)核配置選項不太熟悉時,建議你使用這個工具來進行內(nèi)核配置。

當(dāng)用戶完成配置后,配置工具會自動生成.config文件,它被保存在內(nèi)核代碼樹的根目錄下。用戶可以很容易找到它,當(dāng)然用戶也可以直接對這個文件進行簡單的修改。但是當(dāng)你修改過配置文件之后,你必須通過下面的命令來驗證和更新配置:

make oldconfig

跟2.4版本的不同之處在于,用戶不需要顯示的調(diào)用make dep命令來生成依賴文件,內(nèi)核會自動維護代碼間的依賴關(guān)系。

當(dāng)一切工作完成以后,用戶只需要簡單鍵入make,剩下所有的工作makefile就會自動替你完成了。

3 Makefile編譯流程

當(dāng)用戶使用Linux的Makefile編譯內(nèi)核版本時,Makefile的編譯流程如下:

Ø 使用命令行或者圖形界面配置工具,對內(nèi)核進行裁減,生成.config配置文件

Ø 保存內(nèi)核版本信息到 include/linux/version.h

Ø 產(chǎn)生符號鏈接 include/asm,指向?qū)嶋H目錄 include/asm-$(ARCH)

Ø 為最終目標(biāo)文件的生成進行必要的準(zhǔn)備工作

Ø 遞歸進入 /init 、/core、 /drivers、 /net、 /lib等目錄和其中的子目錄來編譯生成所有的目標(biāo)文件

Ø 鏈接上述過程產(chǎn)生的目標(biāo)文件生成vmlinux,vmlinux存放在內(nèi)核代碼樹的根目錄下

Ø 最后根據(jù) arch/$(ARCH)/Makefile文件定義的后期編譯的處理規(guī)則建立最終的映象bootimage,包括創(chuàng)建引導(dǎo)記錄、準(zhǔn)備initrd映象和相關(guān)處理

4 Makefile關(guān)鍵規(guī)則和定義描述

1) 目標(biāo)定義

目標(biāo)定義是Makefile文件的核心部分,目標(biāo)定義通知Makefile需要生成哪些目標(biāo)文件、如何根據(jù)特殊的編譯選項鏈接目標(biāo)文件,同時控制哪些子目錄要遞歸進入進行編譯。

這個例子Makefile文件位于/fs/ext2目錄 :

#

# Makefile for the linux ext2-filesystem routines.

#

obj-$(CONFIG_EXT2_FS) += ext2.o

ext2-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \

ioctl.o namei.o super.o symlink.o

ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o

ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o

ext2-$(CONFIG_EXT2_FS_SECURITY) += xattr_security.o

ext2-$(CONFIG_EXT2_FS_XIP) += xip.o

這表示與ext2相關(guān)的目標(biāo)文件由 ext2-y定義的文件列表組成,其中ext2-$(*)是由內(nèi)核配置文件.config中的配置項決定,最終Makefile會在這個目錄下統(tǒng)一生成一個目標(biāo)文件ext2.o(由obj-$(CONFIG_EXT2_FS)決定)。其中obj-y表示為生成vmlinux文件所需要的目標(biāo)文件集合,具體的文件依賴于內(nèi)核配置。

Makefile會編譯所有的$(obj-y)中定義的文件,然后調(diào)用鏈接器將這些文件鏈接到built-in.o文件中。最終built-in.o文件通過頂層Makefile鏈接到vmlinux中。值得注意的是$(obj-y)的文件順序很重要。列表文件可以重復(fù),文件第一次出現(xiàn)時將會鏈接到built-in.o中,后來出現(xiàn)的同名文件將會被忽略。文件順序直接決定了他們被調(diào)用的順序,這一點讀者需要特別注意。

讀者可能會在某些Makefile中發(fā)現(xiàn)lib-y定義,所有包含在lib-y定義中的目標(biāo)文件都將會被編譯到該目錄下一個統(tǒng)一的庫文件中。值得注意的是lib-y定義一般被限制在 lib 和arch/$(ARCH)/lib 目錄中。

體系makefile文件和頂層makefile文件共同定義了如何建立vmlinux文件的規(guī)則。

$(head-y) 列舉首先鏈接到vmlinux的對象文件。
$(libs-y) 列舉了能夠找到lib.a文件的目錄。
其余的變量列舉了能夠找到內(nèi)嵌對象文件的目錄。
$(init-y) 列舉的對象位于$(head-y)對象之后。
然后是如下位置順序:
$(core-y), $(libs-y), $(drivers-y) 和 $(net-y)。
頂層makefile定義了所有通用目錄,arch/$(ARCH)/Makefile文件只需增加體系相關(guān)的目錄。
例如: #arch/i386/Makefile
libs-y += arch/i386/lib/

core-y += arch/i386/kernel/ \

arch/i386/mm/ \

arch/i386/$(mcore-y)/ \

arch/i386/crypto/

drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/

drivers-$(CONFIG_PCI) += arch/i386/pci/

…………………………………………

2) 目錄遞歸

Makefile文件只負(fù)責(zé)當(dāng)前目錄下的目標(biāo)文件,子目錄中的文件由子目錄中的makefile負(fù)責(zé)編譯,編譯系統(tǒng)使用obj-y 和 obj-m來自動遞歸編譯各個子目錄中的文件。

對于fs/Makefile:

obj-$(CONFIG_EXT2_FS) += ext2/

如果在內(nèi)核配置文件.config中,CONFIG_EXT2_FS被設(shè)置為y或者m,則內(nèi)核makefile會自動進入ext2目錄來進行編譯。內(nèi)核Makefile只使用這些信息來決定是否需要編譯這個目錄,子目錄中的makefile規(guī)定哪些文件編譯為模塊,哪些文件編譯進內(nèi)核。

3) 依賴關(guān)系

Linux Makefile通過在編譯過程中生成的 .文件名.o.cmd(比如對于main.c文件,它對應(yīng)的依賴文件名為.main.o.cmd)來定義相關(guān)的依賴關(guān)系。

一般文件的依賴關(guān)系由如下部分組成:

Ø 所有的前期依賴文件(包括所有相關(guān)的*.c 和 *.h)

Ø 所有與CONFIG_選項相關(guān)的文件

Ø 編譯目標(biāo)文件所使用到的命令行

位于init目錄下的main.c文件的依賴文件.main.o.cmd內(nèi)容如下,讀者可以結(jié)合起來理解上述文件依賴關(guān)系的三個組成部分:

cmd_init/main.o := gcc -m32 -Wp,-MD,init/.main.o.d -nostdinc -isystem /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include -D__KERNEL__ -Iinclude -Iinclude2 -I/home/linux/linux-2.6.17.11/include -include include/linux/autoconf.h -I/home/linux/linux-2.6.17.11/init -Iinit -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -march=i686 -mcpu=pentium4 -mregparm=3 -ffreestanding -I/home/linux/linux-2.6.17.11/include/asm-i386/mach-default -Iinclude/asm-i386/mach-default -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(main)" -D"KBUILD_MODNAME=KBUILD_STR(main)" -c -o init/.tmp_main.o /home/linux/linux-2.6.17.11/init/main.c

deps_init/main.o := \

/home/linux/linux-2.6.17.11/init/main.c \

$(wildcard include/config/x86/local/apic.h) \

$(wildcard include/config/acpi.h) \

# 由于篇幅的關(guān)系,此處略去一些定義

……………………………………..

include2/asm/mpspec_def.h \

/home/linux/linux-2.6.17.11/include/asm-i386/mach-default/mach_mpspec.h \

include2/asm/io_apic.h \

include2/asm/apic.h \

init/main.o: $(deps_init/main.o)

$(deps_init/main.o):

4) 特殊規(guī)則

特殊規(guī)則使用在內(nèi)核編譯需要規(guī)則定義而沒有相應(yīng)定義的時候。典型的例子如編譯時頭文件的產(chǎn)生規(guī)則。其他例子有體系makefile編譯引導(dǎo)映像的特殊規(guī)則。特殊規(guī)則寫法同普通的makefile規(guī)則。
編譯程序在makefile所在的目錄不能被執(zhí)行,因此所有的特殊規(guī)則需要提供前期文件和目標(biāo)文件的相對路徑。
定義特殊規(guī)則時將使用到兩個變量:
$(src): $(src)是對于makefile文件目錄的相對路徑,當(dāng)使用代碼樹中的文件時

使用該變量$(src)。
$(obj): $(obj)是目標(biāo)文件目錄的相對路徑。生成文件使用$(obj)變量。
例如: #drivers/scsi/Makefile
$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
$(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl
這就是使用普通語法的特殊編譯規(guī)則。
目標(biāo)文件依賴于兩個前提文件。目標(biāo)文件的前綴是$(obj), 前提文件的前綴是

$(src)(因為它們不是生成文件)。

5) 引導(dǎo)映象

體系makefile文件定義了編譯vmlinux文件的目標(biāo)對象,將它們壓縮和封裝成引導(dǎo)代碼,并復(fù)制到合適的位置。這包括各種安裝命令。在Linux中Makefile無法為所有的體系結(jié)構(gòu)提供標(biāo)準(zhǔn)化的方法,因此常需要具體硬件體系結(jié)構(gòu)下makefile提供附加處理規(guī)則。
附加處理過程常位于arch/$(ARCH)/下的boot/目錄。
內(nèi)核編譯體系無法在boot/目錄下提供一種便捷的方法創(chuàng)建目標(biāo)系統(tǒng)文件。因此arch/$(ARCH)/Makefile要調(diào)用make命令在boot/目錄下建立目標(biāo)系統(tǒng)文件。建議使用的方法是在arch/$(ARCH)/Makefile中設(shè)置調(diào)用,并且使用完整路徑引用arch/$(ARCH)/boot/Makefile。
例如: #arch/i386/Makefile
boot := arch/i386/boot
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
建議使用"$(Q)$(MAKE) $(build)=<dir>"方式在子目錄中調(diào)用make命令。
當(dāng)執(zhí)行不帶參數(shù)的make命令時,將首先編譯第一個目標(biāo)對象。在頂層makefile中第一個目標(biāo)對象是all:。
一個體系結(jié)構(gòu)需要定義一個默認(rèn)的可引導(dǎo)映像。
增加新的前提文件給all目標(biāo)可以設(shè)置不同于vmlinux的默認(rèn)目標(biāo)對象。
例如: #arch/i386/Makefile
all: bzImage
當(dāng)執(zhí)行不帶參數(shù)的"make"命令時,bzImage文件將被編譯。

6) 常用編譯命令

if_changed
如果必要,執(zhí)行傳遞的命令。
用法:
$(builtin-target): $(obj-y) FORCE

$(call if_changed,link_o_target)
當(dāng)這條規(guī)則被使用時它將檢查哪些文件需要更新,或命令行被改變。后面這種情況將迫使

重新編譯編譯選項被改變的執(zhí)行文件。使用if_changed的目標(biāo)對象必須列舉在$( builtin-target)中,否則命令行檢查將失敗,目標(biāo)一直會編譯。

if_changed_dep

如果必要,執(zhí)行傳遞的命令并更新依賴文件。

用法:

%.o: %.S FORCE

$(call if_changed_dep,as_o_S)

當(dāng)這條規(guī)則被使用時它將檢查哪些文件需要更新,或命令行被改變。同時它會重新檢測依賴關(guān)系的改變并將生成新的依賴文件。這是與if_changed命令的區(qū)別。

7) 定制命令

當(dāng)正常執(zhí)行帶編譯命令時命令的簡短信息會被顯示(要想顯示詳細(xì)的命令,請在命令行中加入V=1)。要讓定制命令具有這種功能需要設(shè)置兩個變量:
quiet_cmd_<command> - 將被顯示的內(nèi)容
cmd_<command> - 被執(zhí)行的命令
例如: #
quiet_cmd_image = BUILD $@
cmd_image = $(obj)/tools/build $(BUILDFLAGS) \
$(obj)/vmlinux.bin > $@
targets += bzImage
$(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
@echo 'Kernel: $@ is ready'
執(zhí)行make命令編譯$(obj)/bzImage目標(biāo)時將顯示:
BUILD arch/i386/boot/bzImage

8) 預(yù)處理鏈接腳本

當(dāng)編譯vmlinux映像時將使用arch/$(ARCH)/kernel/vmlinux.lds鏈接腳本。
相同目錄下的vmlinux.lds.S文件是這個腳本的預(yù)處理的變體。內(nèi)核編譯系統(tǒng)知曉.lds

文件。并使用規(guī)則*lds.S -> *lds。
例如: #arch/i386/kernel/Makefile
always := vmlinux.lds
#Makefile
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
$(always)賦值語句告訴編譯系統(tǒng)編譯目標(biāo)是vmlinux.lds。$(CPPFLAGS_vmlinux.lds)

賦值語句告訴編譯系統(tǒng)編譯vmlinux.lds目標(biāo)的編譯選項。
編譯*.lds時將使用到下面這些變量:
CPPFLAGS : 定義在頂層Makefile
EXTRA_CPPFLAGS : 可以設(shè)置在編譯的makefile文件中
CPPFLAGS_$(@F) : 目標(biāo)編譯選項。注意要使用文件全名。

9) 主機輔助程序的編譯

內(nèi)核編譯系統(tǒng)支持在編譯階段編譯主機可執(zhí)行程序。為了使用主機程序需要兩個步驟:第一個步驟使用hostprogs-y變量告訴內(nèi)核編譯系統(tǒng)有主機程序可用。第二步給主機程序添加潛在的依賴關(guān)系。有兩種方法,在規(guī)則中增加依賴關(guān)系或使用$(always)變量。這一部分的內(nèi)容相對于其他內(nèi)核文件的編譯要簡單的多,感興趣的讀者可以參考scripts/Makefile.build中的相關(guān)內(nèi)容。

10) Clean機制

clean命令清除在編譯內(nèi)核生成的大部分文件,例如主機程序,列舉在 $(hostprogs-y)、$(hostprogs-m)、$(always)、$(extra-y)和$(targets)中目標(biāo)文件都將被刪除。代碼目錄數(shù)中的"*.[oas]"、"*.ko"文件和一些由編譯系統(tǒng)產(chǎn)生的附加文件也將被刪除。
附加文件可以使用$(clean-files)進行定義。
例如: #drivers/pci/Makefile
clean-files := devlist.h classlist.h
當(dāng)執(zhí)行"make clean"命令時, "devlist.h classlist.h"兩個文件將被刪除。內(nèi)核編譯系統(tǒng)默認(rèn)這些文件與makefile具有相同的相對路徑,否則需要設(shè)置以'/'開頭的絕對路徑。
刪除整個目錄使用以下方式:
例如: #scripts/package/Makefile
clean-dirs := $(objtree)/debian/
這樣就將刪除包括子目錄在內(nèi)的整個debian目錄。如果不使用以'/'開頭的絕對路徑內(nèi)核編譯系統(tǒng)見默認(rèn)使用相對路徑。
通常內(nèi)核編譯系統(tǒng)根據(jù)"obj-* := dir/"進入子目錄,但是在體系makefile中需要顯式使用如下方式:
例如: #arch/i386/boot/Makefile
subdir- := compressed/
上面賦值語句指示編譯系統(tǒng)執(zhí)行"make clean"命令時進入compressed/目錄。
在編譯最終的引導(dǎo)映像文件的makefile中有一個可選的目標(biāo)對象名稱是archclean。
例如: #arch/i386/Makefile
archclean:
$(Q)$(MAKE) $(clean)=arch/i386/boot
當(dāng)執(zhí)行"make clean"時編譯器進入arch/i386/boot并象通常一樣工作。arch/i386/boot 中的makefile文件可以使用subdir-標(biāo)識進入更下層的目錄。
注意1: arch/$(ARCH)/Makefile不能使用"subdir-",因為它被包含在頂層makefile文件中,在這個位置編譯機制是不起作用的。
注意2: 所有列舉在core-y、libs-y、drivers-y和net-y中的目錄將被"make clean"命令清除。

4 小結(jié)

隨著Linux的飛速發(fā)展,越來越多的開發(fā)人員將關(guān)注的焦點集中到Linux的研究和開發(fā)上。如果想對Linux內(nèi)核進行研究和開發(fā),就必須首先熟悉Linux 內(nèi)核Makefile的組織和編譯過程。目前Linux最新的穩(wěn)定內(nèi)核版本為2.6.17,但是當(dāng)今絕大部分對于Linux Makefile的介紹都是基于2.4內(nèi)核的,可以說關(guān)于2.6內(nèi)核Makefile相關(guān)的文章鳳毛麟角,我特意抽時間完成了這篇分析文章,讓讀者迅速熟悉Linux最新Makefile體系,從而加深對內(nèi)核的理解,同時也希望能對Linux在公司的推廣起到一定的推動作用。


本文來自CSDN博客,http://blog.csdn.net/mbtrend/archive/2008/10/05/3016889.aspx

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉