Tasche
Tasche

Reputation: 65

CMakeLists.txt not in root directory, can't do an automatic build

I have an issue with a repository not having its CMakeLists in the root directory, namely https://github.com/lz4/lz4 The CMakeLists.txt is in the subfolder contrib/cmake_unofficial.

I already checked similar questions on SO (Is it possible to have cmake build file (CMakeLists.txt) not in root in CLion, cmake - CMakeLists.txt is not in root folder (but is included in source)), but they only provide alternatives, and not a solution applicable to my situation.

Heres the cmake module I came up with:

if(ENABLE_LZ4)
    message(STATUS "Using LZ4.")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_LZ4")

    # Enable ExternalProject CMake module
    include(ExternalProject)

    set(LZ4_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/lz4)
    set(LZ4_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib)
    # Download and install lz4
    ExternalProject_Add(
        lz4
        GIT_REPOSITORY https://github.com/lz4/lz4.git
        GIT_TAG dev
        SOURCE_DIR ${LZ4_SOURCE_DIR}
        BINARY_DIR ${LZ4_BINARY_DIR}
        INSTALL_COMMAND ""
        CMAKE_ARGS
            ${LZ4_SOURCE_DIR}/contrib/cmake_unofficial
            -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
    )

    # Get lz4 source and binary directories from CMake project
    ExternalProject_Get_Property(lz4 source_dir binary_dir)

    # Create a liblz4 target to be used as a dependency by the program
    add_library(liblz4 IMPORTED SHARED GLOBAL)
    add_dependencies(liblz4 lz4)

    include_directories(
        ${LZ4_SOURCE_DIR}/lib
    )
    set(LZ4_LIB ${LZ4_BINARY_DIR}/liblz4.so)
else()
    message(STATUS "Not using LZ4.")
    set(LZ4_LIB "")
endif()

Here the complete error output:

[  0%] Performing update step for 'lz4'
Current branch dev is up to date.
[  1%] Performing configure step for 'lz4'
CMake Error: The source directory "/****/build/lz4" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
CMakeFiles/lz4.dir/build.make:105: recipe for target 'lz4-prefix/src/lz4-stamp/lz4-configure' failed
make[2]: *** [lz4-prefix/src/lz4-stamp/lz4-configure] Error 1
CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/lz4.dir/all' failed
make[1]: *** [CMakeFiles/lz4.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2

I tried adding the path 'contrib/cmake_unofficial' to the CMAKE_ARGS variable (as seen in the module above), but it does not work (seems to be ignored?).

I also tried using PATCH_COMMAND to copy the CMakeLists.txt to the root before the build starts, but the relative paths of the file get messed up. In other words, i need the cmake command to be called to build the library to be : cmake contrib/cmake_unofficial.

I also tried using CONFIGURE_COMMAND for this, but keep getting a file not found error for some reason (even though the path is correct). The module has some other issues too, but I'm only interested in the non-root CMakeLists.

Thanks in advance!

Upvotes: 2

Views: 2191

Answers (2)

Tasche
Tasche

Reputation: 65

Probably not the correct way to do it, but this seems to work for me. I used the CONFIGURE_COMMAND to call cmake on the correct directory. Then use BUILD_COMMAND to call make So essentially, it breaks down to this:

ExternalProject_Add(
    lz4
    GIT_REPOSITORY https://github.com/lz4/lz4.git
    GIT_TAG dev
    SOURCE_DIR ${LZ4_SOURCE_DIR}
    BINARY_DIR ${LZ4_BINARY_DIR}
    CONFIGURE_COMMAND cmake ${LZ4_SOURCE_DIR}/contrib/cmake_unofficial
    BUILD_COMMAND make
    INSTALL_COMMAND ""
    CMAKE_ARGS
        -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
)

Upvotes: 1

Tsyvarev
Tsyvarev

Reputation: 66143

ExternalProject separates download and source directories:

  • DOWNLOAD_DIR - a directory where downloading step is performed
  • SOURCE_DIR - a directory used as a source one when configuration step is performed

When use git for extract the project, note that git clone is called from the download directory, where it creates new directory with a project sources.

set(LZ4_DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/lz4)
# Set a source dir based on the download one.
set(LZ4_SOURCE_DIR ${LZ4_DOWNLOAD_DIR}/lz4/contrib/cmake_unofficial)
set(LZ4_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib)
# Download and install lz4
ExternalProject_Add(
    lz4
    DOWNLOAD_DIR ${LZ4_DOWNLOAD_DIR} # Set download directory explicitely
    GIT_REPOSITORY https://github.com/lz4/lz4.git
    GIT_TAG dev
    SOURCE_DIR ${LZ4_SOURCE_DIR}
    BINARY_DIR ${LZ4_BINARY_DIR}
    ...
)

Upvotes: 2

Related Questions