On Wed, Nov 27, 2013 at 4:38 AM, Michael Putters <michael.putt...@binarygenetics.com> wrote: > Hello, > > I have started migrating a somewhat large (mostly) C++ project to Gradle, > coming from a set of Visual Studio solutions, various makefiles and random > oddities. Basically it has to build for Windows, Linux, OS X, iOS, Android > and Windows Phone, with some glue here and there on the mobile targets. > > Having spent some time with the latest Gradle builds, I have some questions > and suggestions. Keep in mind that those questions consider Gradle is > already capable of building for all those targets: just assume I'll provide > the pull requests to make it happen, I just need to know how it should be > done. > > > 1. What is the simplest way to have a source set apply to only one target > platform? > > For example, with this setup: > > sources { > main { > cpp { } > objcpp { } > } > } > > targetPlatforms { > windows { } > ios { } > } > > How can I easily say "use the objcpp sourceset only for the ios target > platform"? Or possibly the other way around, "for the ios target platform, > use the cpp and objcpp sourcesets". I guess each has its own advantages :).
Yes, the native world does travel into code that should only be included when targeting certain platform/architectures. in current existing paradigms, such as nmake/GNU make, this is usually handled though per-file bases that are combined into source 'trees' Gradle-wise, it seems like being able to utilize include & exclude patterns/rules to the source sets would make the most sense. > > 2. Could the DSL for target platforms be improved? > > Right now, platforms hold information about the architecture and operating > system. I believe it would make sense to extend this information for each > supported platform type in order to provide extra information for that > platform. Basically, you'd get something like this: > > targetPlatforms { > > windows(Win32) { > sdk '8.1' // include path for Windows > SDK 8.1 > version '6.2' // #define _WIN32_WINNT > 0x0602 (same as version target: '6.2') > unicode true // #define _UNICODE "unicode" as true/false is neglecting the ascii vs multi-byte distinction, so I'd personally look to go for something more along the lines of "charset" with "ascii", "unicode", "multi-byte" accepted values, and this would define _UNICODE or _MBCS as applicable. > icon name: 'MyApp' // fill the icon > information in a .rc > productName 'MyApp' // fill the product > information in a .rc (defaults to the project name) > productVersion '1.0.0.0' // fill the version > information in a .rc (defaults to the project version) > companyName 'My Company' // fill the company > information in a .rc (defaults to the project group) > } > > ios(iOS) { > sdk '7.1' // -isysroot version or > path > version min: '6.0' target: '7.1' // minimum and target > versions > frameworks 'Foundation', 'UIKit' // link with > sdk/System/Library/Framework/Foundation.framework/Foundation, ... > icon name: 'MyApp' prerendered: true // fill the CFBundleIcons > information in a .plist > productName 'MyApp' // fill the product > information in a .plist (defaults to the project name) > productVersion '1.0.0.0' // fill the version > information in a .plist (defaults to the project version) > } > > android(Android) { > sdk '19' // Android SDK version or > path > ndk 'r9b' // Android NDK version or > path > version min: '17' target: '19' // minimum and target > versions (<uses-sdk/>) > icon name: 'MyApp' // fill the <application > android:icon="xx"/> in the Android manifest > productName 'MyApp' // fill the <application > android:label="xx"/> in the Android manifest (defaults to the project name) > productVersion '1.0.0.0' // fill the <manifest > android:versionName="xx"/> in the Android manifest (defaults to the project > version) > } > } > > targetArchitectures { > > x64 { > platforms targetPlatforms.windows, targetPlatforms.linux, > targetPlatforms.osx > } > > armv8 { > platforms targetPlatforms.ios, targetPlatforms.android > } > > } > > Right now the Windows SDK directory information is part of > VisualCppToolchain, but some people could want to build their Windows > application with other compilers. Also, in the example above, some of the > properties are applicable to multiple platforms. And having the > architectures separated from the platforms means you don't have to duplicate > information just because you want both an x86 and an x64 Win32 build. > What is "other compilers" here? Microsoft has historically seemingly had no care to make their headers to be compatible with any other compiler other than VS. In the past I have attempted to do this, but the headers are so full of VS-isms that it's impossible to use in any other compiler without modifications, unless that compiler is strictly VS compliant, such as Intel's on Windows. So, that completely rules what comes to mind for me at least, which is MinGW... But MinGW comes with its own set of Windows headers and doesn't require the Windows SDK in any form, though last I looked at the headers, they were primarily baselined to Windows XP still... (which is not gradle's problem) > > 3. How to properly share the resource.h file for Windows builds? > > I already mentioned it in https://github.com/gradle/gradle/pull/225 but it > makes more sense here: > > - .rc files generally include resource.h (which defines most of your > resource constants) > - said resource.h is then used from your C or C++ code to reference the > resources > > Right now, if I put resource.h in src/main/rc, it seems wrong to include > "../rc/resource.h" from src/main/cpp. Something like exportedHeaders seems > closer to the right solution but then it's just shared with another > sourceset, not really exported from that particular component. How could > this be made to work nicely? > I would suggest that gradle look at splitting "headers" or "include" (which ever the final naming for it comes to be) to have "private" and "public" (or similarly concepted) subtrees. - I've seen some proprietary compilation infrastructures have a "protected" subtree, but I'm not sure as to how applicable that is here. both subtrees both be included when building the project, but only the "public" tree gets published/included by projects depending on it. This would allow for the scenario stated above and other cases where non-external/API code needs to share function (declarations) and structures/classes. I've not yet looked at how the rc (visual studio) or windres (mingw) support is currently, but given that it is 'resources' I was somewhat expecting it to utilize/copy the current concepts from java-based languages with the "resources" folder trees, is it not this way? > > 4. Can we change/add some default values? > > Namely: > > 1) use src/xx/include instead of src/xx/headers, which is far more > conventional and intuitive to C/C++ developers > 2) add default include's to source sets: **/*.cpp for C++, **/*.c for C, etc > There probably should be the ability to apply filters like suggested, but I believe that should be included into the support done for the platform-specific code to avoid confusion with two different sets of filtering. But I am against applying such filters automatically. 1) we often use .cxx extensions for C++ files, and also .cc is another commonly used one out in the wild. 2) some generated code we have to deal with uses non default/standard extensions (such as gSOAP and its .nsmap file) that needs to be compiled as C/C++ So I'm of the opinion that anything in the source folders should be automatically be treated as source, and the user can apply filters to exclude what they need to be excluded specifically. > Right now, by default, we're compiling every header found in src/xx/cpp > (again not very intuitive). > > > That's about it for now :) > > > > Michael > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email