CMake cannot find my library file

I want to use CMake to create a simple static library Maths

and then link to that library to create a simple executable Alpha

.

Here's my directory structure:

/Maths
    /build
        /
    /CMakeLists.txt
    /maths.cpp
    /maths.h
/Alpha
    /build
        /
    /CMakeLists.txt
    /main.cpp

      

And here are the contents of those files:

* CMakeLists.txt (for Maths) *

cmake_minimum_required(VERSION 2.6)
project(Maths)
add_library(maths STATIC maths.cpp)

      

* maths.cpp *

int Double(int x)
{
    int y = x * 2;
    return y;
}

      

* maths.h *

int Double(int x);

      

* CMakeLists.txt (for Alpha) *

cmake_minimum_required(VERSION 2.8)
project(Alpha)
add_executable(alpha main.cpp ../Maths/maths.h)
target_link_libraries(maths ../Maths/build/libmaths.a)

      

* main.cpp *

#include <iostream>

#include "maths.h"

using namespace std;

int main()
{
    int x = 5;
    int y = Triple(x);
    cout << "The answer = " << y << endl;
    return 0;
}

      

So, I go into the directory /Maths/build

and run cmake ..

. Then I ran make

. This creates a library file libmaths.a

in the directory /Maths/build

.

Then I go into the directory /Alpha/build

and run cmake ..

. Then I ran make

. However, this gives me an error:

/usr/bin/ld: cannot find -lmaths

      

Why can't I find the library file I just created?

I also tried to copy libmaths.a

and maths.h

to directory /Alpha

and change Alpha CMakeLists.txt to:

cmake_minimum_required(VERSION 2.8)
project(Alpha)
add_executable(alpha main.cpp maths.h)
target_link_libraries(maths libmaths.a)

      

But this gave the same error.

+3


source to share


2 answers


The significant issue is that it libmaths.a

doesn't fit in one of the default linker directories. The big problem is what you moved libmaths.a

to target_link_libraries

.

This is bad for several reasons, but the most obvious one is that it is not completely portable. Another compiler toolchain might use a different end than .a

for static libraries, so you won't be able to build it. Also, if you ever decide to switch to dynamic linking in the future, it means reorganizing existing CMake scripts.



The correct solution is not to pass hard-coded filenames to target_link_libraries

. There are two paths you can take to avoid this.

  • Use find script. Essentially, you call find_library(MY_MATHLIB maths [...])

    and then execute target_link_libraries(alpha ${MY_MATHLIB})

    . This will figure out the absolute path of the file in a .a

    portable way and pass it to the linker. The biggest disadvantage of this approach is that the file .a

    must already be available for a successful search. So if you want to build maths

    after running CMake for, alpha

    or build it as a part alpha

    , it won't work.

  • Since both libraries are under your control, consider using the CMake packaging mechanism . This is by far the most user-friendly approach to build, but unfortunately also the hardest to set up. If you're willing to spend some time researching the CMake docs and experimenting with build, I recommend you give it a try, but if you just want something that works fast, you might want to stick with option 1.

+3


source


Use CMakeLists.txt

in the root directory

/CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT( MyProject )
ADD_SUBDIRECTORY( Maths )
ADD_SUBDIRECTORY( Alpha )

      



in Alpha / CMakeLists.txt:

TARGET_LINK_LIBRARIES( alpha maths ) 

      

Run CMake on top level CMakeLists.txt instead of separate subdirectories

+2


source







All Articles