# \[SOLVED\] \[Native build\] Conditional sources sets

**URL:** <https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261>\
**Category:** Help/Discuss\
**Created:** [April 21, 2015, 11:01pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261 "2015-04-21T23:01:48Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 21, 2015, 11:01pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/1 "2015-04-21T23:01:48Z")

</div>

Hi guys,

I’m new to Gradle, but successfully used it in no time for Java/Groovy projects.

Now, I’m trying to write a Gradle native build script for a multiplatform C/C++ project which has common sources, and specific ones for each “platform”. I couldn’t find in the [documentation](https://gradle.org/docs/current/userguide/nativeBinaries.html) how to configure this situation.

Is there a way to specify sources conditionally (for example, using something like _toolChain in VisualCpp_) or by other means?

If not, I guess I can use different components for each “platform”. In this scenario, is there a way to share sources between components?

Thanks in advance. I would appreciate any thoughts/directions on this.

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [April 22, 2015, 2:02am UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/2 "2015-04-22T02:02:57Z")

</div>

You can add source sets conditionally:

```gradle
model {
    components {
        main(NativeExecutableSpec) {
            binaries.all {
                if (targetPlatform.operatingSystem.windows) {
                    sources {
                        winSrc(CppSourceSet) {
                            // configure it
                        }
                    }
                }
            }
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 22, 2015, 2:06pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/3 "2015-04-22T14:06:02Z")

</div>

Hi Sterling,

Thanks for your response.

1. The condition targetPlatform.operatingSystem.windows is never met. I guess the operating system is not defined by default or I’m missing something.

2. If I remove the if (targetPlatform.operatingSystem.windows) I get the following error:

Any thoughts?  
Thanks again.

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [April 22, 2015, 3:54pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/4 "2015-04-22T15:54:18Z")

</div>

Can you post your build.gradle? Are you using 2.3 or a nightly?

It’s doing the same thing as this snippet:  
[http://gradle.org/docs/current/userguide/nativeBinaries.html#componentBinarySettings](http://gradle.org/docs/current/userguide/nativeBinaries.html#componentBinarySettings)

Do you have your check for targetPlatform inside `binaries.all {}`?

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 22, 2015, 3:58pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/5 "2015-04-22T15:58:11Z")

</div>

By trial and error I found a solution.

I had to define the platforms in order to get the condition met (I’m trying to generate a VS project on OSX):

```
win32 {
    architecture "x86"
    operatingSystem "windows"
}

osx32 {
     architecture "x86"
     operatingSystem "osx"
}

```

… etc …

Also, I could specify another set using this syntax:

```
sources {
    if (targetPlatform.operatingSystem.windows) {
        cpp {
             source {
        	// Configure
            }
        }
    }
}

```

However I’m still having an issue. My project has the following structure:

code/src/ - Common sources  
code/src/platform/windows - Windows sources  
code/src/platform/osx - OSX sources  
… etc …  
code/include/ - Common headers  
code/include/platform/windows - Windows headers  
code/include/platform/osx - OSX headers  
… etc …

In the global source set I have to exclude “platform”:

```
sources {
    cpp {
        source {
            srcDir "code/src"
            include " **/*.cpp", "** /*.c"
            exclude "platform"
        }
					
        exportedHeaders {
            srcDir "code/include"
            include "**/*.h"
            exclude "platform"
        }
    }
}

```

Then for each platform I add a source set. But the global exclude seems to prevent the specific sources from being included. Is there a way to avoid this? Or can I somehow define each different source set a with a different name?

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 22, 2015, 9:19pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/6 "2015-04-22T21:19:10Z")

</div>

> [@butaca](#):
>
> But the global exclude seems to prevent the specific sources from being included. Is there a way to avoid this? Or can I somehow define each different source set a with a different name?

@sterling Any thoughts? Thank you very much for your time.

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [April 22, 2015, 10:09pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/7 "2015-04-22T22:09:51Z")

</div>

You need to create new source sets for the OS-specific sets of sources. `cpp` is the source set that’s provided by the cpp plugin by default. You can create new ones like:

```gradle
// in a binaries block
if (targetPlatform.operatingSystem.windows) {
   sources {
      mySourceSet(CppSourceSet) {
         // configure it
      }
   }
}

```

RIght now you’re configuring `cpp` to exclude and include the platform specific sources.

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 22, 2015, 10:43pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/8 "2015-04-22T22:43:22Z")

</div>

Yes. That’s the first thing I tried but I’m getting the following error:

```
Cannot create a CppSourceSet because this type is not known to this container. Known types are: NativeExecutableSpec, NativeLibrarySpec

```

This is a minimal grade.build throwing this error:

```
apply plugin: 'cpp'
apply plugin: 'visual-studio'

model {
    buildTypes {
        Debug
        Release
    }

    platforms {
        win32 {
            architecture "x86"
            operatingSystem "windows"
        }

        osx32 {
            architecture "x86"
            operatingSystem "osx"
        }
    }

    components {
        myLib(NativeLibrarySpec) {
            targetPlatform "win32"
            targetPlatform "osx32"

            sources {
                cpp {
                    source {
                        srcDir "code/src"
                        include "**/*.cpp"
                        exclude "platform"
                    }

                    exportedHeaders {
                        srcDir "code/include"
                        include "**/*.h"
                        exclude "platform"
                    }
                }
            }

            binaries.all {
                if (targetPlatform.operatingSystem.windows) {
                    sources {
                        win(CppSourceSet) {
                            srcDir "code/src"
                            include "platform/windows/**/*.cpp"
                        }
                    }
                }
            }
        }
    }
}
```

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [April 22, 2015, 10:55pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/9 "2015-04-22T22:55:06Z")

</div>

Can you post your `model {}` block?

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 22, 2015, 10:56pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/10 "2015-04-22T22:56:10Z")

</div>

> [@sterling](#):
>
> Can you post your model {} block?

Just updated my previous post with that info.

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [April 22, 2015, 11:16pm UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/11 "2015-04-22T23:16:07Z")

</div>

Ah, you’re missing a `source {}`

```gradle
sources {
    win(CppSourceSet) {
        source {
           srcDir "code/src"
           include "platform/windows/**/*.cpp"
        }
    }
}

```

I think you could get away with just `source.srcDir 'code/src/platform/windows'` and `source.include "**/*.cpp"` too.

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 23, 2015, 1:31am UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/12 "2015-04-23T01:31:00Z")

</div>

That’s it! I was missing the **source {}**. Thank you very much for your time.

I know it made a silly mistake and I missed it in the [DSL documentation](http://gradle.org/docs/current/dsl/org.gradle.language.cpp.CppSourceSet.html), but maybe IMHO the error message could be more informative. Is there a way I can “report” it?

Thank you again.

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [April 23, 2015, 1:45am UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/13 "2015-04-23T01:45:53Z")

</div>

There’s a lot of active development in that area (the error message from the latest nightly is very different, still not very useful), but I’ll let the guys know.

@erdi this is probably the sort of thing that’ll happen frequently.

---

<div class="post-metadata">

**Author:** ![butaca](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/butaca/32/2275_2.png) [@butaca](https://discuss.gradle.org/u/butaca)\
**Post date:** [April 23, 2015, 2:29am UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/14 "2015-04-23T02:29:54Z")

</div>

Ok, thanks.

Awesome work. Gradle is outstanding.

Thanks again.

---

<div class="post-metadata">

**Author:** ![erdi](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/erdi/32/24_2.png) [@erdi](https://discuss.gradle.org/u/erdi)\
**Post date:** [April 23, 2015, 8:27am UTC](https://discuss.gradle.org/t/solved-native-build-conditional-sources-sets/9261/15 "2015-04-23T08:27:46Z")

</div>

@sterling, yeah this is all tinkered with as we speak. The error message should definitely be more helpful.
