0

My project struct is like this:

.
├── CMakeLists.txt       ->1
├── external
│   └── libuv
│       ├── CMakeLists.txt      ->2
│       ├── include
│       │   ├── uv
│       │   │   ├── errno.h
│       │   │   ├── linux.h
│       │   │   ├── threadpool.h
│       │   │   ├── unix.h
│       │   │   └── version.h
│       │   └── uv.h
│       └── libuv.a
└── test_libuv
    ├── CMakeLists.txt        ->3
    └── test_libuv.cc

the 1st CMakeLists.txt's content is:

cmake_minimum_required(VERSION 3.12)
project(test5)
set(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
add_subdirectory(external/libuv)
add_subdirectory(test_libuv)

the 2nd CMakeLists.txt's content is:

project(uv)
cmake_minimum_required(VERSION 3.20)

add_library(uv STATIC IMPORTED)
set_target_properties(
  uv  PROPERTIES
  IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libuv.a
)

target_include_directories(
  uv
  INTERFACE
  ${CMAKE_CURRENT_LIST_DIR}/include
)

It imports a precompiled static library, and specify the include directory of the target.

The 3rd CMakeLists.txt's content is like this:

cmake_minimum_required(VERSION 3.12)
project(test_libuv)
set(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")

add_executable(
  test_libuv test_libuv.cc
)

add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../external/libuv uv)

target_link_libraries(test_libuv
PRIVATE
uv

It import the uv target and link it to test_libuv.cc.

The content of test_libuv.cc is:

#include "uv.h"

int main() {

}

It just include the uv.h. But the compile complains fatal error: 'uv.h' file not found .

I thought the header file directory of libuv is added to uv target in the 2nd CMakeLists.txt by target_include_directories. And it will be passed to test_libuv's include path when the add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../external/libuv uv) is called.

But it shows the libuv's header directory is not add to test_libuv's include path. I guess the key point is that libuv is a precompiled library, but I don't know how to fix it. Could someone help me? Thanks a lot.

Joey
  • 175
  • 7
  • When a `CMakeLists.txt` included via `add_subdirectory` defines an IMPORTED target, this target is not visible to the main `CMakeLists.txt` by default. So your call `target_link_libraries(test_libuv PRIVATE uv)` links with the plain library name `uv`, not with the **target**. You could easily detect that if use "namespaced" names for IMPORTED targets: CMake will give an error for the line `target_link_libraries(test_libuv PRIVATE uv::uv)` if no target `uv::uv` exists in the current scope. – Tsyvarev Nov 23 '22 at 14:04
  • @Tsyvarev Thanks a lot for your reply. I use ```find_package``` and ```include_directories``` to add libuv's header file directory directly to ```test_libuv```'s include path, and it compiles ok. But I am not sure is there a better way. Because I must specify libuv's header file directory in test_libuv's CMakeLists.txt. Is there some way I just import the libuv target and use its head files and library? – Joey Nov 24 '22 at 02:18
  • "Is there some way I just import the libuv target and use its head files and library?" - You have read the duplicate question and have found there `GLOBAL` keyword, haven't you? – Tsyvarev Nov 24 '22 at 07:39
  • Sorry I didn't notice the top of this page. Thanks a lot. – Joey Nov 24 '22 at 09:32

0 Answers0