使用Gradle管理依赖项,并在旧式C++;项目 我试图逐步将一个非常混乱的遗留C++项目迁移到Gradle。

使用Gradle管理依赖项,并在旧式C++;项目 我试图逐步将一个非常混乱的遗留C++项目迁移到Gradle。,gradle,build.gradle,Gradle,Build.gradle,tl;dr 该项目由一个过于复杂的shell脚本系统编译,每个模块都包含一个额外的.txt文件,其中包含依赖项。这些.txt文件由shell脚本解析,并按照您编写它们的顺序进行编译(是的,如果您以错误的顺序编写依赖项,编译将失败) 编译结果放在三个常用目录中:exe用于可执行文件,i686用于*。so文件(exe64和x86_64,在64位的情况下)包括中间.h文件和后续编译所需的其他文件的目录。在为Windows而非Linux编译时也会发生同样的情况,但现在我主要关注Linux的编译 这是存储

tl;dr

该项目由一个过于复杂的shell脚本系统编译,每个模块都包含一个额外的
.txt
文件,其中包含依赖项。这些
.txt
文件由shell脚本解析,并按照您编写它们的顺序进行编译(是的,如果您以错误的顺序编写依赖项,编译将失败)

编译结果放在三个常用目录中:
exe
用于可执行文件,
i686
用于
*。so
文件(
exe64
x86_64
,在64位的情况下)
包括中间
.h
文件和后续编译所需的其他文件的
目录。在为Windows而非Linux编译时也会发生同样的情况,但现在我主要关注Linux的编译

这是存储库的外观:

root
├── dependency
│   └── shared-dependency
└── project
    ├── exe
    ├── i686
    ├── includes
    │   ├── 32
    │   └── 64
    ├── lib1
    ├── lib2
    ├── lib3
    ├── lib4
    ├── (other directories)
    └── main
shared dependency
是第一个编译的依赖项,第二个是
main
模块(可执行文件),然后是一些
libs
。对于
libs
,正如我所说,依赖项是在
libs
文件夹中定义的

始终编译
共享依赖项
模块,但不编译库:您选择编译的库将根据其
txt
文件中定义的依赖项定义要编译的内容。例如,
lib6
中的
txt
文件包含字符串
lib2 lib1 lib5
,因此构建过程将按以下顺序编译:
shared dependency
main
lib2
lib1
lib5
lib6
lib10
中的
txt
文件包含字符串
lib2 lib5 lib28 lib8
,因此构建过程将以此顺序为:
shared dependency
main
lib2
lib5
lib28
lib8
lib10

现在,如果您创建一个新的库,您必须手动定义它的所有依赖项,并将它们写入txt文件(按正确的顺序!),以便能够构建它

问题

作为此次迁移的第一步,我的目标是使用Gradle:

  • 调用构建脚本(不要使用Gradle的构建,我会将其留到迁移的后期,因为我必须拆开那些凌乱的脚本才能做到这一点)
  • 定义依赖项(好处是:在库的子文件夹中定义每个依赖项,并且不要污染根
    build.gradle
  • 我已在
    project
    目录中创建了一个Gradle项目,并以编程方式定义了它在
    settings.Gradle
    文件中包含的所有子文件夹,并在
    build.Gradle
    文件中定义了构建任务:

    allprojects {
        task build {
            exec {
                commandLine "sh", "build.sh"
            }
        }
    }
    
    project(':lib1') {
        dependencies {
            archives project(':main')functionalities
        }
    }
    
    但是我不能定义依赖项!如果我在
    build.gradle
    文件中添加类似的内容:

    allprojects {
        task build {
            exec {
                commandLine "sh", "build.sh"
            }
        }
    }
    
    project(':lib1') {
        dependencies {
            archives project(':main')functionalities
        }
    }
    
    无论我选择什么来代替
    归档
    这个词(比如
    实现
    ),Gradle都会抱怨

    Could not find method archives() for arguments [project ':main'] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
    

    我是Gradle的新手,但如果我的理解是正确的,我必须应用插件才能使用依赖项,例如
    apply plugin:'base'
    。但是如果我这样做,我就不能再定义构建任务了,因为我得到
    无法添加任务“build”,因为已经存在同名任务。
    。如果我尝试使用
    task build它将虽然令人沮丧,但最终我还是实现了我想要的

    settings.gradle:

    rootDir.eachDir { f ->
    if(!f.getName().startsWith(".") &&
           !f.getName().startsWith("include") &&
           !f.getName().startsWith("lib") &&
           !f.getName().startsWith("lib64") &&
           !f.getName().startsWith("exe") &&
           !f.getName().startsWith("i686") &&
           !f.getName().startsWith("x86_64") ) {
            include f.getName()
        }
    }
    
    这将包括作为模块的所有子目录

    root build.gradle:

    defaultTasks 'build'
    
    allprojects {
        task build {
            doLast {
                exec {
                    commandLine 'sh', "${project.name}.sh", '32', 'all'
                }
            }
        }
    }
    
    build {
        dependsOn ":lib1:build"
        dependsOn ":lib2:build"
        dependsOn ":lib6:build"
    }
    
    这将为每个子模块调用自定义构建脚本。请注意,我必须在根项目中添加一个空项目_name.sh,否则Gradle会抱怨文件丢失。我不知道是否有安装程序告诉他不要尝试调用根目录中的构建脚本,我仍然必须对此进行研究

    子模块build.gradle的示例:

    defaultTasks 'build'
    
    allprojects {
        task build {
            doLast {
                exec {
                    commandLine 'sh', "${project.name}.sh", '32', 'all'
                }
            }
        }
    }
    
    build {
        dependsOn ":lib1:build"
        dependsOn ":lib2:build"
        dependsOn ":lib6:build"
    }
    
    这定义了子模块是当前模块的依赖项

    就这样