1

I have a simple JNI-based project up to experiment with the nar-maven-plugin. I'm running Windows 10 and am using MinGW compilers. I'm compiling the native code as C++ rather than C, although I don't think that matters for this question. (The native implementations in the "real" project will use C++, so just changing this is not trivial once I move beyond this initial test.)

In order to make this build with maven install via the Eclipse IDE, I need to specify the linker explicitly in the POM file as part of the plug-in configuration. The relevant section is here:

        <plugin>
            <groupId>com.github.maven-nar</groupId>
            <artifactId>nar-maven-plugin</artifactId>
            <version>3.5.1</version>
            <extensions>true</extensions>
            <configuration>
                <linker>
                    <name>g++</name>
                    <options>
                        <option>-Wl,--kill-at</option>
                    </options>
                </linker>
                <libraries>
                    <library>   
                        <type>jni</type>
                        <narSystemPackage>com.mycompany.sandbox</narSystemPackage>
                    </library>
                </libraries>
            </configuration>
        </plugin>

If I do this, then I'm good on my local machine, but I believe that I've specialized my POM to certain machines / linkers. If I take it out completely, then I get this error:

[INFO] --- nar-maven-plugin:3.5.1:nar-validate (default-nar-validate) @ nar-test ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.786 s
[INFO] Finished at: 2017-06-29T17:05:34-04:00
[INFO] Final Memory: 8M/23M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.github.maven-nar:nar-maven-plugin:3.5.1:nar-validate (default-nar-validate) on project nar-test: Execution default-nar-validate of goal com.github.maven-nar:nar-maven-plugin:3.5.1:nar-validate failed. NullPointerException -> [Help 1]

If I leave the <name>g++</name> part and delete just the options, then it compiles but my test fails because it cannot link to the native implementation at run-time. (That's related to the --kill-at flag and a known issue, so it's not a terrible surprise.)

Is there a known way to handle this issue such that I get a machine-independent POM that works?

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Brick
  • 3,998
  • 8
  • 27
  • 47

2 Answers2

1

This is a typical use case for Build Profiles:

However, sometimes portability is not entirely possible. [...] And at still other times, you may even need to include a whole plugin in the build lifecycle depending on the detected build environment.

So, put your different plugin configurations into profiles and activate them accordingly while building.

An alternative is to use a property like:

<option>${options}</option>

that's defined with a value like the following in case:

mvn ... -Doptions=-Wl,--kill-at
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • This will allow me to change the value explicitly set. What I need to do is get the default behavior except in the one case. It seems that would involve removing tags, not just changing the values on a case-by-case basis. Can I use this without enumerating all of the cases? – Brick Jun 30 '17 at 01:01
  • @Brick Have you seen the following on the page I linked: "_Profiles listed in the `` tag would be activated by default every time a project use it._"? See also the edit to my answer. – Gerold Broser Jun 30 '17 at 07:42
  • The specific direction that you're suggesting still seems to be moving me farther down the path that I don't want to follow, but I did work out a profile-based solution that I wouldn't have gotten without your help. I'm +1 on this answer for cases where it may help, but I've posted my specific solution separately in this case. – Brick Jun 30 '17 at 14:35
  • @Brick That's fine. Glad that I could be of help. It's not the opposite, however (though, I agree, that might not be clear from my short answer). If I had supplied a POM example it'd looked exactly like yours. The next step in my answer plan was to add such an example but since you worked it out yourself... + the working POM config → +1.5 from me for you. – Gerold Broser Jun 30 '17 at 20:28
  • In that case, I guess my comment illustrates how deeply confused I was at the point that I was writing the question and even the answer! – Brick Jun 30 '17 at 20:33
1

The answer by Gerold Broser seems to be the opposite of what I wanted, but it did get me on the right path of using profiles. One of the tricks for me was to realize that it's ok to do a partial specification of an individual plugin in the profile while putting other parameters for that same plugin in the main build section. Although not needed in this case since I don't need to specify anything different in the default situation, I also came to the conclusion that I'd have wanted activeByDefault on my default settings rather than using activeProfiles as was suggested.

For completeness, the relevant parts of the working POM are below:

<profiles>
    <!-- This default not needed since is specifies nothing, but this seems to be the correct syntax if it were needed
    <profile>
        <id>Default-CPP-Tools</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    -->

    <profile>
        <id>Windows-MinGW</id>
        <activation>
            <os>
                <family>Windows</family>
            </os>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>com.github.maven-nar</groupId>
                    <artifactId>nar-maven-plugin</artifactId>
                    <version>3.5.1</version>
                    <extensions>true</extensions>
                    <configuration>
                        <linker>
                            <name>g++</name>
                            <options>
                                <option>-Wl,--kill-at</option>
                            </options>
                        </linker>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

<build>
    <defaultGoal>integration-test</defaultGoal>

    <plugins>
        <plugin>
            <groupId>com.github.maven-nar</groupId>
            <artifactId>nar-maven-plugin</artifactId>
            <version>3.5.1</version>
            <extensions>true</extensions>
            <configuration>
                <libraries>
                    <library>
                        <type>jni</type>
                        <narSystemPackage>com.mycompany.sandbox</narSystemPackage>
                    </library>
                </libraries>
            </configuration>
        </plugin>
    </plugins>

</build>
Brick
  • 3,998
  • 8
  • 27
  • 47