# GENERATE\_NATIVE\_HEADERS target is not recognized as INTERFACE type

**URL:** https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048
**Category:** Usage
**Created:** [October 22, 2020, 10:01pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048 "2020-10-22T22:01:06Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [October 22, 2020, 10:01pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/1 "2020-10-22T22:01:06Z")

</div>

target\_include\_directories failed when target (myprojJNI below) is a target that was created by add\_jar GENERATE\_NATIVE\_HEADERS option.  
ERROR: CMake Error at …CMakeLists.txt:… (target\_include\_directories):  
target\_include\_directories may only set INTERFACE properties on INTERFACE  
targets"  
This target was created with

```auto
 add_jar(myprojJava
        SOURCES ${JNI_SRC}
        INCLUDE_JARS ${JNI_CLASSPATH}
        GENERATE_NATIVE_HEADERS myprojJNI)

```

Here myprojJNI is a target and documenation said :  
“using option GENERATE\_NATIVE\_HEADERS, native header files can be generated for methods declared as native. These files provide the connective glue that allow your Java and C code to interact. An INTERFACE target will be created for an easy usage of generated files. Sub-option DESTINATION can be used to specify the output directory for generated header files” So myprojJNI must be INTERFACE target and therefore allow target\_include\_directories setting like

```auto
target_include_directories(myprojJNI
        PUBLIC #<-- Wrong, it must match myprojJNI target type which is INTERFACE
            $<INSTALL_INTERFACE:${ARCH}/include>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
)

```

So why is this error occuring?  
Note 1, there is also another error "Could NOT find JNI (missing: JNI\_DIR)  
" at the begging of CMakeLists in the  
find\_package(JNI PATHS /opt/jdk/jdk8)

but cmake documentation said JNI is recommended for using  
GENERATE\_NATIVE\_HEADERS, but despite JNI package is not found, the JNI native\_headers are generated ok under the build tree when target\_include\_directories and myprojJNI installation code is bypassed (UseJava.cmake : set (\_add\_jar\_GENERATE\_NATIVE\_HEADERS\_DESTINATION "${CMAKE\_CURRENT\_BINARY\_DIR}${CMAKE\_FILES\_DIRECTORY}/${\_TARGET\_NAME}.dir/native\_headers)  
Note 2. The purpose of caling target\_include\_directories(myprojJNIis to fix an error occurring when install(TARGETWS myprojJNI … ) indicating that myprojJNIis property INTERFACE\_INCLUDE\_DIRECTORIES contains path to build tree and source tree which is because default value for the native\_headers is under ${CMAKE\_CURRENT\_BINARY\_DIR}.  
So the bigger question is more general how to install and export target with dependency on GENERATE\_NATIVE\_HEADERS target like myprojJNI which seems blocked by the default INTERFACE\_INCLUDE\_DIRECTORIES pointing to CMAKE\_CURRENT\_BINARY\_DIR.

```auto
target_link_libraries(myprojlibShared
        ...myprojJNI ...)
....

install(TARGETS myprojlibShared myprojJNI .. 
          EXPORT myExportTargets ...
)
# had to add myprojJNI to avoid error indicating myprojlibShared dependency on myprojJNI

```

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [October 23, 2020, 6:01am UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/2 "2020-10-23T06:01:54Z")

</div>

> [@yisseamake](#):
>
> So myprojJNI must be INTERFACE target and therefore allow target\_include\_directories setting like

Your example after this uses `PUBLIC` instead of `INTERFACE`. I’m guessing that’s why you see the error message complaining that you may only set `INTERFACE` properties on `INTERFACE` targets.

For your other JNI-related questions, I will have to defer to others for follow-up (@marc.chevrier perhaps?).

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [October 23, 2020, 9:05am UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/3 "2020-10-23T09:05:00Z")

</div>

For error on `find_package(JNI ...)`: you don’t use correctly the command. As specified in [FindJNI](https://cmake.org/cmake/help/latest/module/FindJNI.html) documentation, you have to set `JAVA_HOME` variable **before** calling `find_package`:

```cmake
set(JAVA_HOME /opt/jdk/jdk8)
find_package(JNI)

```

And for the export, I don’t understand your problem. But, first, `target_link_libraries` does not have option `EXPORT`. And why do you want to install the JNI interface? It is just headers!! Use keyword `PRIVATE` to link the jNI interface to avoid problems…  
The following snippet works as expected:

```cmake
add_jar(myprojJava
        SOURCES ${JNI_SRC}
        INCLUDE_JARS ${JNI_CLASSPATH}
        GENERATE_NATIVE_HEADERS myprojJNI)
add_library(myprojlibShared SHARED ...)
target_link_libraries(myprojlibShared PRIVATE myprojJNI)
install(TARGETS myprojlibShared EXPORT libShared DESTINATION /to/install/path)
export (EXPORT libShared NAMESPACE proj::)
install(EXPORT libShared DESTINATION /to/install/path/EXPORT NAMESPACE proj::)

```

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [October 23, 2020, 2:47pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/4 "2020-10-23T14:47:11Z")

</div>

Thank you again! I changed to interface :

```auto
target_include_directories(myprojJNI
        INTERFACE #must match myprojJNI target type which is INTERFACE
            $<INSTALL_INTERFACE:${ARCH}/include>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
)

```

This passes Configure phase, However this still causes error  
in install(TARGETS:

```auto
target_link_libraries(myprojlibShared
        ...myprojJNI ...)

install(TARGETS myprojlibShared myprojJNI .. 
          EXPORT myExportTargets ...
)

```

ERROR

```auto
CMake Error in ... src/CMakeLists.txt:
Target "myprojJNI" INTERFACE_INCLUDE_DIRECTORIES property contains
  path:
    "..build/.../src/CMakeFiles/myprojJava.dir/native_headers"
  which is prefixed in the build directory <!--[Y] Of course it is in build directory bc UseJava.cmake sets it in ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers -->
the followed by other error:
Target "myprojJNI" INTERFACE_INCLUDE_DIRECTORIES property contains
  path:
    "..build/.../src/CMakeFiles/myprojJava.dir/native_headers"
  which is prefixed in the source directory <!--[Y]This is wrong since this directory is under build and identified by the previous error as build tree path. -->
then next error 
Target "myprojJNI" INTERFACE_INCLUDE_DIRECTORIES property contains
  path:
    ..../src/JAVA_INCLUDE_PATH-NOTFOUND" <!-- [Y] Indeed is in the source tree, which again indicate previous error is incorrect as path starting from build is not in source dir.-->
  which is prefixed in the source directory
<!-- [Y] for this error note, that Java is found, only JNI is not found as per response to Marc-->

```

So adding target\_include\_directories(myprojJNI INTERFACE …) does not change the default path for native\_headers which is set by GENERATE\_NATIVE\_HEADERS option. Could you please advise on these errors and in general how to install a target dependent on a target created by GENERATE\_NATIVE\_HEADERS option.

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [October 23, 2020, 4:21pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/5 "2020-10-23T16:21:34Z")

</div>

Thank you very much for you response Marc. I am sorry I swapped 2 lines in my original post, I fixed this typo so EXPORT is in the right place. In summary set(JAVA\_HOME /opt/jdk/jdk8) does not help with finding JNI and making myprojJNI PRIVATE in target\_link\_libraries(myprojlibShared PRIVATE myprojJNI) does not resolve errors shown in my response to Craig below.  
Before calling find\_package(JNI), I call find\_package(Java) and it reports success

```auto
Found Java: /opt/jdk/jdk8/bin/java (found version "1.8.0_161") 

```

despite JNI package is not found, cmake is able to create native\_headers. So for this that I could trigger somehow INTERFACE\_INCLUDE\_DIRECTORIES settings without NOTFOUND JNI path instances this problem would be solved. I don’s think direct set(INTERFACE\_INCLUDE\_DIRECTORIES is agood idea, but do you know of better approach ?  
So the main problem is to avoid errors shown in my response to Craig below

```auto
CMake Error in ... src/CMakeLists.txt:
Target "myprojJNI" INTERFACE_INCLUDE_DIRECTORIES property contains
  path:
    "..build/.../src/CMakeFiles/myprojJava.dir/native_headers"
  which is prefixed in the build directory <!--[Y] Of course it is in build directory bc UseJava.cmake sets it in ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers -->

```

Here I tried your suggestion target\_link\_libraries(myprojlibShared PRIVATE myprojJNI)  
and the same errors still there

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [October 23, 2020, 4:33pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/6 "2020-10-23T16:33:28Z")

</div>

If `JNI` is not found, may be there is some problem on the installation of Java jdk…

Again, why do you want to export the target generated by `GENERATE_NATIVE_HEADERS`? It is not required to export your library `myprojlibShared`.

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [October 23, 2020, 6:54pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/7 "2020-10-23T18:54:08Z")

</div>

If I drop myprojJNI from the list of targets in the install(TARGETS, then error occurs (below ) indicating that dependendee target myprojlibShared needs its dependency myprojJNI because they are linked by  
target\_link\_libraries(myprojlibShared  
…myprojJNI …)  
install(TARGETS myprojlibShared myprojJNI … #need myprojJNI bc it was linked  
EXPORT myExportTargets …  
)

ERROR: CMake Error: install(EXPORT “myExportTargets” …) includes target “myprojlibShared” which requires target “myprojJNI” that is not in any export set.

In regards to JNI not found (smaller problem), it got fixed after adding

```auto
set(CMAKE_FIND_ROOT_PATH "${JAVA_HOME}")
set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH "${JAVA_HOME}")

```

before find\_package(JNI)

The problem was caused by find\_package(JNI) search path considering only /opt/xxxx and /opt/toolchains while jni.h is located at /opt/jdk/jdk8/include/jni.h. Debugging was done with set(CMAKE\_FIND\_DEBUG\_MODE TRUE) enabling printout of /opt/cmake/share/cmake-3.17/Modules/FindJNI.cmake:341 looking for jni.h find\_path considered the following locations list

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [October 23, 2020, 10:22pm UTC](https://discourse.cmake.org/t/generate-native-headers-target-is-not-recognized-as-interface-type/2048/8 "2020-10-23T22:22:10Z")

</div>

The problem has been worked- around by adding DESTINATION path in the add\_jar

```auto
add_jar(myprojJava
        SOURCES ${JNI_SRC}
        INCLUDE_JARS ${JNI_CLASSPATH}
        GENERATE_NATIVE_HEADERS myprojJNI 
               DESTINATION ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}
}

```

This means cmake behavior is problematic because GENERATE\_NATIVE\_HEADERS default destination is inside the build tree set (\_add\_jar\_GENERATE\_NATIVE\_HEADERS\_DESTINATION "${CMAKE\_CURRENT\_BINARY\_DIR}${CMAKE\_FILES\_DIRECTORY}/${\_TARGET\_NAME}.dir/native\_headers) and this does not allow installation of the native\_headers. The native\_headers need to be installed for the upstream project to use library which is built with these headers.
