zoukankan      html  css  js  c++  java
  • Scons 五:完整的工程

    工程的组织目录如下:

    ├── core

    │   ├── inc

    │   │   └── bsp.h

    │   ├── SConscript

    │   ├── src

    │   │   ├── fsm.c

    │   │   ├── fsm.h

    │   │   ├── log.c

    │   │   ├── log.h

    │   │   └── SConscript

    │   ├── test1.c

    │   └── test1.h

    ├── main.c

    ├── phy

    │   ├── inc

    │   │   └── phy_inc.h

    │   ├── SConscript

    │   ├── src

    │   │   └── Sconscript

    │   ├── test2.c

    │   └── test2.h

    ├── Sconstruct

    └── wifi

        ├── inc

        │   └── protol.h

        ├── SConscript

        ├── src

        │   └── SConscript

        ├── test3.c

    └── test3.h

    分成3个模块core,phy,wifi。每个模块目录下都有inc和src两个文件夹。分别放.h和.c文件。首先来看core模块

    Inc中包含bsp.h文件

    内容如下。定义了x变量

    #define x 1

    Src下面分别有fsm.c, fsm.h,log.c,log.h,SConscript

    Fsm.c

    #include <stdio.h>

    #include "fsm.h"

    void fsm_print()

    {

        printf("fsm_log_level=%d ",fsm_level);

        printf("fsm_print ");

    }

    Fsm.h

    #define fsm_level 1

    void fsm_print();

    log.c

    #include <stdio.h>

    #include "log.h"

    void log_print()

    {

        printf("log_print ");

    }

    log.h

    void log_print();

    SConscript的内容。编译所有的.c文件并且返回所有的obj文件

    from SCons.Script import *

    from scons.SCons import *

    Import('env')

    source_file_list=[]

    def find_source_file():

        for file in os.listdir(os.getcwd()):

            if file.endswith('.c'):

                c_path=os.path.join(os.getcwd(),file)

                source_file_list.append(c_path)

    find_source_file()

    fsm_object=env.Object(source_file_list)

    Return('fsm_object')

    在core目录下有test1.c,test1.h, SConscript

    Tets1.c

    #include <stdio.h>

    #include "bsp.h"

    void core_test()

    {

        printf("x=%d ",x);

        printf("core_test1 ");

    }

    Test1.h

    void core_test();

    SConscript

    import sys

    import os

    import re

    from SCons.Script import *

    from scons.SCons import *

    Import('env')

    subdir = ''

    subdir +='src '

    source_file_list=[]

    include_file_list=[]

    incdir = ''

    incdir +='inc '

    object_list=[]

    def find_source_file():

        for file in os.listdir(os.getcwd()):

            if file.endswith('.c'):

                c_path=os.path.join(os.getcwd(),file)

                source_file_list.append(c_path)

    def scons_script_recursive():

        print("scons_script_recursive,subdir=%s " % subdir)

        subdir_list=subdir.split(' ')

        print(subdir_list)

        subdir_list.pop()

        for dir in subdir_list:

            dir_path=os.path.join(os.getcwd(),dir)

            obj=SConscript(os.path.join(dir_path,'SConscript'))

            object_list.append(obj)

    def get_include_path():

        dir_tmp=incdir.split(' ')

        dir_tmp.pop()

        for include_file in dir_tmp:

            include_file_path=os.path.join(os.getcwd(),include_file)

            include_file_path_env=include_file_path+' '

            env.Append(include=include_file_path_env)

            include_file_list.append(include_file_path)

    scons_script_recursive()

    get_include_path()

    find_source_file()

    core_object=env.Object(source_file_list,CPPPATH=include_file_list)

    object_list.append(core_object)

    env.Library('core',object_list)

    1 首先递归的执行子目录下的SConscript,并且将返回的obj对象append到object_list

    2 找到当前目录下所有的.c文件并编译成object文件append到object_list

    3 将object_list中的所有.o文件打包成.a文件供后面连接使用

    同样的步骤适合phy和wifi模块

    Phy模块test2.c

    #include <stdio.h>

    #include "phy_inc.h"



    void phy_test()

    {

        printf("phy=%d ",phy);

        printf("phy_test1 ");

    }

    Test2.h

    void phy_test();

    phy_inc.h

    #define phy 3

    wifi模块

    test3.c

    #include <stdio.h>

    #include "protol.h"

    void wifi_test()

    {

        printf("version=%d ",version);

        printf("wifi_test1 ");

    }

    Test3.h

    void wifi_test();

    protol.h

    #define version 4

    最后main.c的代码如下:

    #include <stdio.h>

    #include "test1.h"

    #include "test2.h"

    #include "test3.h"

    #include "fsm.h"

    #include "log.h"



    void main()

    {

        printf("test1.c ");

        iot_core_test();

        phy_test();

        wifi_test();

        fsm_print();

        log_print();

    }

    SConscript:

    import sys

    import os

    import re

    from SCons.Script import *

    from scons.SCons import *

    from build_software import *

    env = Environment()

    env['subdir']='core '

    env.Append(subdir='phy ')

    env.Append(subdir='wifi ')

    env['include']=''

    Export('env')

    print(env['subdir'])

    source_file_list=[]

    target='main'

    link_path=['core','phy','wifi']

    obj_list=[]

    obj_path_list=[]

    include_path_list=[]

    inc_path = 'core/src '

    def find_source_file():

        for file in os.listdir(os.getcwd()):

            if file.endswith('.c'):

                source_file_list.append(file)

    def find_all_object_file():

        complete_path=[]

        for link in link_path:

            complete_path.append(os.path.join(os.getcwd(),link))

        for path in complete_path:

            for root,dir,files in os.walk(path):

                for f in files:

                    if f.endswith('.o'):

                        print(f)

                        obj_path_list.append(root)

                        obj_list.append(f)

    def find_all_include_path():

        tmp_path_list=inc_path.split(' ')

        for tmp_path in tmp_path_list:

            tmp_path=os.path.join(os.getcwd(),tmp_path)+' '

            env.Append(include=tmp_path)

        include_path=env['include'].split(' ')

        include_path.pop()

        for path in include_path:

            include_path_list.append(path)

        for l in link_path:

            include_path_list.append(os.path.join(os.getcwd(),l))

    def get_target():

        Progress("get_target")

        main=env.Program('main.c',CPPPATH=include_path_list,LIBS=obj_list)

    subdir_path=env['subdir'].split(' ')

    subdir_path.pop()

    def sub_scons():

        path_list=[]

        for scons_file in subdir_path:

            path=os.path.join(os.getcwd(),scons_file)

            path_list.append(os.path.join(path,'SConscript'))

        SConscript(path_list)

        complete_flag=True

    sub_scons()

    find_source_file()

    find_all_include_path()

    env.Append(LIBPATH=['./core','./phy','./wifi'])

    env.Program('main.c',CPPPATH=include_path_list,LIBS=link_path)

    1 执行子目录的SConscript文件

    2 找到当前目录下的所有c文件

    3 找到所有的include路径

    4 设置外部链接library的路径和名称,最终编译main.c文件

    最终执行结果:

    scons: Reading SConscript files ...

    scons_script_recursive,subdir=src

    ['src', '']

    scons: done reading SConscript files.

    scons: Building targets ...

    gcc -o core/src/fsm.o -c core/src/fsm.c

    gcc -o core/src/log.o -c core/src/log.c

    gcc -o core/test1.o -c -Icore/inc core/test1.c

    ar rc core/libcore.a iot_core/src/fsm.o iot_core/src/log.o core/test1.o

    ranlib core/libiot_core.a

    gcc -o main.o -c -Iiot_core/inc -Iphy/inc -Iwifi/inc -Iiot_core/src -I. -Iiot_core -Iphy -Iwifi main.c

    gcc -o phy/test2.o -c -Iphy/inc phy/test2.c

    ar rc phy/libphy.a phy/test2.o

    ranlib phy/libphy.a

    gcc -o wifi/test3.o -c -Iwifi/inc wifi/test3.c

    ar rc wifi/libwifi.a wifi/test3.o

    ranlib wifi/libwifi.a

    gcc -o main main.o -Liot_core -Lphy -Lwifi -lcore -lphy -lwifi

    scons: done building targets.

    如果我们想将目标文件安装到系统路径中去,也就是可以运行命令的方式那样运行目标文件。可以用install的方式。

    在Sconstruct的最后几行修改如下:将最终编译的文件安装到/usr/local/bin目录下

    tar=env.Program('main.c',CPPPATH=include_path_list,LIBS=link_path)
    env.Install('/usr/local/bin',tar)
    env.Alias('install','/usr/local/bin')

    执行命令sudo scons install

    会增加如下的打印:表示main安装到了/usr/local/bin下

    Install file: "main" as "/usr/local/bin/main"

  • 相关阅读:
    js事件之event.preventDefault()与event.stopPropagation()用法区别
    [转] The program can't start because api-ms-win-crt-runtime-l1-1-0.dll is missing
    [转] Visual Studio Code behind a proxy
    [转] js == 与 === 的区别
    [转]说说C#的async和await
    [转]Sublime Text3注册码(可用)
    Oracle 12c
    SQL Server死锁
    Initialize the Storage Emulator by Using the Command-Line Tool
    Microsoft Fakes
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/13130035.html
Copyright © 2011-2022 走看看