我正在为嵌入式设备创建一个虚拟机(VM),它通过编译字节码来运行C和Java代码。 现在我正在尝试自动编译和刷新C应用程序(Java已经可以工作)。
一个重要的手动部分是获取.c文件并将其转换为VM理解的格式。 目前,它的工作原理如下:
启动Docker容器,同时将其指向.c文件所在的位置并给自己bash
〜$ docker run -i -v / home / git / bytecode_manipulation:/ c_files -t lljvm_work / bin / bash
使用容器配置的lljvm-cc工具转换.c文件,同时生成jasmin文件(转换为字节码的中间件)
docker_container $ lljvm-cc test_c_srv.c -o test_c_srv -g3
退出docker容器并运行python脚本,将.j jasmin文件转换为.uj jasmin文件,将.uj文件转换为.class文件并将其放入一个好文件夹
〜$ ./script_j_to_uj.py test_c_srv.j test_srv.uj
我想在Makefile中自动执行此操作。 目前,我在makefile中有一个配方,它为Java应用程序生成.class文件,然后挖掘所有.class文件(来自C或Java应用程序)。将它们进一步处理成.raw_ujc文件并生成一个列表。理想情况下,这也会为C应用程序生成.class文件。 食谱:
jre_filelist:
CLASSPATH=$(SELF)/default_runtime/real:$(SELF)/default_runtime/fake:$(SELF)/default_runtime/fake/uj \
javac $(SELF)/default_runtime/real/java/lang/*.java $(SELF)/default_runtime/UJSrv.java
find $(SELF)/ -iname "Exception.class" -type f > $(SELF)/files #First call is overwriting
find $(SELF)/ -iname "Runnable.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "String.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "StringBuilder.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "Thread.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "Throwable.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "UJSrv.class" -type f >> $(SELF)/files
$(info findstring C in $(LANG) is $(findstring C, $(LANG)))
ifeq ($(findstring C, $(LANG)),C) # include C runtime
CLASSPATH=$(SELF)/default_runtime/real:$(SELF)/default_runtime/fake:$(SELF)/default_runtime/fake/uj:$(SELF)/lljvm \
javac $(SELF)/lljvm/runtime/*.java
CLASSPATH=$(SELF)/default_runtime/real:$(SELF)/default_runtime/fake:$(SELF)/default_runtime/fake/uj:$(SELF)/lljvm \
javac $(SELF)/lljvm/lib/*.java
find $(SELF)/lljvm/runtime -iname "*.class" -type f >> $(SELF)/files
find $(SELF)/lljvm/lib -iname "*.class" -type f >> $(SELF)/files
$(foreach SRV, $(SRVS_C), \
find $(UJ_DIR)/services/c/ -iname "$(SRV).class" -type f | xargs realpath >> $(SELF)/files && \
) true
endif
$(foreach SRV, $(SRVS_JAVA), \
CLASSPATH=$(SELF)/default_runtime javac $(UJ_DIR)/services/java/$(SRV).java && \
find $(UJ_DIR)/services/java/ -iname "$(SRV).class" -type f | xargs realpath >> $(SELF)/files && \
) true
@while read -r file; do \
$(CMD) "$$file" >/dev/null; \
done < $(SELF)/files;
rm -f $(SELF)/files && rm -f ../filelist.txt
find $(SELF)/default_runtime/ -iname "*.raw_ujc" -type f > ../filelist.txt
ifeq ($(findstring C, $(LANG)),C) # include C runtime
find $(SELF)/lljvm/ -iname "*.raw_ujc" -type f >> ../filelist.txt
endif
$(foreach SRV, $(SRVS_C), \
find $(UJ_DIR)/services/c/ -iname "$(SRV).raw_ujc" -type f | xargs realpath >> ../filelist.txt && \
) true
$(foreach SRV, $(SRVS_JAVA), \
find $(UJ_DIR)/services/java/ -iname "$(SRV).raw_ujc" -type f | xargs realpath >> ../filelist.txt && \
) true
所以做这些步骤有点困难,我希望得到建议。主要是引导容器或预先启动容器并为其提供命令。
答案 0 :(得分:0)
在摆弄后,我做了我想要的事情:
compile_c:
docker run -v $(UJ_DIR)/services/c/:/c_files -w /c_files -it lljvm_work \
/bin/bash -c '../usr/local/lib/lljvm/lljvm-cc $(SRV).c -l_c_support -o $(SRV) -g3'
sudo python script_j_to_uj.py $(UJ_DIR)/services/c/$(SRV).j $(UJ_DIR)/services/c/$(SRV).uj
rm -f $(UJ_DIR)/services/c/$(SRV)
在配方中,使用如下:
jre_filelist:
CLASSPATH=$(SELF)/default_runtime/real:$(SELF)/default_runtime/fake:$(SELF)/default_runtime/fake/uj \
javac $(SELF)/default_runtime/real/java/lang/*.java $(SELF)/default_runtime/UJSrv.java
find $(SELF)/ -iname "Exception.class" -type f > $(SELF)/files #First call is overwriting
find $(SELF)/ -iname "Runnable.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "String.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "StringBuilder.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "Thread.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "Throwable.class" -type f >> $(SELF)/files
find $(SELF)/ -iname "UJSrv.class" -type f >> $(SELF)/files
$(info findstring C in $(LANG) is $(findstring C, $(LANG)))
ifeq ($(findstring C, $(LANG)),C) # include C runtime
CLASSPATH=$(SELF)/default_runtime/real:$(SELF)/default_runtime/fake:$(SELF)/default_runtime/fake/uj:$(SELF)/lljvm \
javac $(SELF)/lljvm/runtime/*.java
CLASSPATH=$(SELF)/default_runtime/real:$(SELF)/default_runtime/fake:$(SELF)/default_runtime/fake/uj:$(SELF)/lljvm \
javac $(SELF)/lljvm/lib/*.java
# find $(SELF)/default_runtime/real/java/lang/lljvm/util -iname "*.class" -type f >> $(SELF)/files
# find $(SELF)/default_runtime/real//java/lang/lljvm/tools -iname "*.class" -type f >> $(SELF)/files
# find $(SELF)/default_runtime/real//java/lang/lljvm/tools/info -iname "*.class" -type f >> $(SELF)/files
# find $(SELF)/default_runtime/real//java/lang/lljvm/tools/ld -iname "*.class" -type f >> $(SELF)/files
find $(SELF)/lljvm/runtime -iname "*.class" -type f >> $(SELF)/files
# find $(SELF)/default_runtime/real//java/lang/lljvm/io -iname "*.class" -type f >> $(SELF)/files
find $(SELF)/lljvm/lib -iname "*.class" -type f >> $(SELF)/files
$(foreach SRV, $(SRVS_C), \
make compile_c SRV=$(SRV) && \
find $(UJ_DIR)/services/c/ -iname "$(SRV).class" -type f | xargs realpath >> $(SELF)/files && \
) true
endif
$(foreach SRV, $(SRVS_JAVA), \
CLASSPATH=$(SELF)/default_runtime javac $(UJ_DIR)/services/java/$(SRV).java && \
find $(UJ_DIR)/services/java/ -iname "$(SRV).class" -type f | xargs realpath >> $(SELF)/files && \
) true
@while read -r file; do \
$(CMD) "$$file" >/dev/null; \
done < $(SELF)/files;
rm -f $(SELF)/files && rm -f ../filelist.txt
find $(SELF)/default_runtime/ -iname "*.raw_ujc" -type f > ../filelist.txt
ifeq ($(findstring C, $(LANG)),C) # include C runtime
find $(SELF)/lljvm/ -iname "*.raw_ujc" -type f >> ../filelist.txt
endif
$(foreach SRV, $(SRVS_C), \
find $(UJ_DIR)/services/c/ -iname "$(SRV).raw_ujc" -type f | xargs realpath >> ../filelist.txt && \
) true
$(foreach SRV, $(SRVS_JAVA), \
find $(UJ_DIR)/services/java/ -iname "$(SRV).raw_ujc" -type f | xargs realpath >> ../filelist.txt && \
) true