3

I currently have two C projects on Clion with cmake. One of the projects is named "sharedLibsDemo" and I am trying to create a shared library in this project. In the other project I want to use the library that was created by the "shared" project.

Currently, in the "sharedLibsDemo" project I have the following cmake:

cmake_minimum_required(VERSION 3.7)
project(sharedLibsDemo)

set(CMAKE_C_STANDARD 11)
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
set(SOURCE_FILES shared.c shared.h main.c)
add_library(shared SHARED ${SOURCE_FILES})
include(GenerateExportHeader)
GENERATE_EXPORT_HEADER(shared           # generates the export header shared_EXPORTS.h automatically
        BASE_NAME shared
        EXPORT_MACRO_NAME SHARED_EXPORTS
        EXPORT_FILE_NAME shared_EXPORTS.h
        STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC) 

set(EXEC_FILES main.c)
add_executable(myexe ${EXEC_FILES})
target_link_libraries(myexe shared)

However, this cmake only creates the shared_EXPORTS.h, libshared.dll, and libshared.dll.a` files. I managed to create the .lib file using Mingw itself and put all of these files including the .h file of the source code into one folder and placed the folder in the root folder of the second project in order to use it.

However, I've looked everywhere to find a way to link the library into the second project's executable. The documentation for cmake itself assumes I have a tonne of knowledge which I don't. Is there any list of commands that I can use to finally link my library. I have already tried the generic answer of "use find_package() or target_link_libraries" to no avail.

EDIT 1

The following is the contents of shared.h :

#include "shared_EXPORTS.h"
#ifndef SHAREDLIBSDEMO_LIBRARY_H
#define SHAREDLIBSDEMO_LIBRARY_H

void SHARED_EXPORTS sharedHello(void);

#endif

As per the suggestion of @Shmuel H. I placed the shared.h shared.c and the cmakelist.txt for the shared project into a folder in the project that I want to include the library in. And I used add_subdirectory() and target_link_libraries().

The following is the CMakeLists.txt for the project:

cmake_minimum_required(VERSION 3.7)
project(projectFiles)

set(CMAKE_C_STANDARD 11)
include_directories(src ${maker_INCLUDE_DIR})
set(SOURCE_FILES src/nv_runner/main.c src/FactParser/FactParser.c src/FactParser/FactParser.h src/Utils/Utils.c src/Utils/Utils.h src/nv_runner/main.h)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_package(maker REQUIRED)

include_directories(${maker_INCLUDE_DIR})

set(LIBSHARED_LOCATION ${PROJECT_SOURCE_DIR}/libshared)
add_subdirectory(libshared)
include_directories(${LIBSHARED_LOCATION})

add_executable(${PROJECT_NAME} ${SOURCE_FILES} src/FactParser/FactParser.c src/FactParser/FactParser.c src/FactParser/FactParser.h src/nv_runner/main.h)

target_link_libraries(${PROJECT_NAME} ${maker_LIBRARY})
target_link_libraries(${PROJECT_NAME} shared)

At first, I had to remove the SHARED_EXPORTS macro from the sharedHello function and the shared_EXPORTS.h include in shared.h because otherwise it would not recognize the function for use in other files. But when I ran the program I got this result:

Process finished with exit code -1073741515 (0xC0000135)

EDIT 2

Project setup image

In the screenshot, I've taken all the necessary files from the shared project, placed it in a directory in the current project and marked the directory as a Library. The cmake can be seen in the image. With this setup, whenever I run my program, it just crashes with the error seen in the image.

H.Rahimy
  • 300
  • 3
  • 14
  • I could not understand the problem. Do you want to link `shared` to `myexe`? What are the results? What are the expected results? Can you provide the output of `cmake` and `cmake --builld`? – Shmuel H. Apr 28 '17 at 13:16
  • The cmake that I provided is of the sharedLibsDemo project. The exe is there in this project just for me to test. What I really want to accomplish is to be able to take the library produced by this cmake and be able to use it in other clion/cmake projects – H.Rahimy Apr 28 '17 at 13:25
  • the main resources I used for this are http://gernotklingler.com/blog/creating-using-shared-libraries-different-compilers-different-operating-systems/ and http://stackoverflow.com/questions/33062728/cmake-link-shared-library-on-windows – H.Rahimy Apr 28 '17 at 13:28
  • then, you should include this directory as a subdirectory in your project. For example if you have the project `Base` and you want to use the target `shared` from this cmake file, you should include if with `add_subdirectory` and then you can use it in `Base`'s CMakeLists.txt (e.g. `target_link_libraries(myexe shared)`) – Shmuel H. Apr 28 '17 at 13:39
  • I will try that now, but is this the standard practice for creating and using libraries? If I start a whole new project and I only need the functions etc from `shared` or I want to contribute this library to other projects, is this the standard way to go? – H.Rahimy Apr 28 '17 at 13:49
  • Also, what if I want to use an external shared library given to me by someone else – H.Rahimy Apr 28 '17 at 13:54
  • Sorry for the delay, I think that this is the standard way of including other modules. Even third-party modules (as long as you distribute them with your source tree). You could also just link an external dll file, but cmake would not recompile it if its source files has changed. – Shmuel H. Apr 28 '17 at 14:46
  • Alright, I understand now. But the problem I have been facing and trying to resolve is linking external dll files. I don't know how I can get the .lib file from the `shared` library. I used MinGw to make the current one using `gcc -Dshared_EXPORTS -c shared.c` and `gcc -shared -o shared.dll shared.o -Wl,--out-implib,libshared_dll.lib` but whatever method I found on the internet to import external dll libraries didnt work for me. – H.Rahimy Apr 28 '17 at 14:54
  • Could you point me in the right direction on how I can go about doing this? – H.Rahimy Apr 28 '17 at 15:01
  • `target_link_libraries(target )` is the way to go. `` can be also a path to the library. (e.g. `target_link_libraries(exe "path/to/library.dll")`) – Shmuel H. Apr 28 '17 at 15:34
  • I tried this just now with the dll, dll.a present in folder called libshared. `target_link_libraries(${PROJECT_NAME} libshared/libshared.dll)` Got the following errors `c:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../../mingw32/bin/ld.exe: cannot find -llibshared/libshared.dll collect2.exe: error: ld returned 1 exit status CMakeFiles\projectFiles.dir\build.make:151: recipe for target 'projectFiles.exe' failed CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/projectFiles.dir/all' failed mingw32-make.exe[2]: *** [projectFiles.exe] Error 1` There where more lines but can't include here – H.Rahimy Apr 28 '17 at 15:46
  • If I do in fact need the .lib file also, the cmake from the `shared` project does not generate it. I will make one with MinGW now with the commands I shared from before. But should the .lib file also be placed in the same directory as the dll's? – H.Rahimy Apr 28 '17 at 15:53
  • Adding the .lib creating by MinGW yields the same result as not having it at all – H.Rahimy Apr 28 '17 at 16:04

1 Answers1

5

I found out what the issue was. I did not know that the dll had to be in the same folder as the exe, that's why the program was not executing. Once I placed the .dll file inside the exe folder, it worked. Credit goes to this question for helping me identify the issue: C++ running file with included library failes without compiling error (CMake / CLion)

And I found out that .lib files are only necessary for MSVC compiler. MinGW uses the .dll.a file; replacing .lib. This post lead me to finding this out: Compatibility of *.dll *.a *.lib *.def between VisualStudio and gcc

Please correct me if I'm wrong however. Here is an image of my current project and cmake setup

Community
  • 1
  • 1
H.Rahimy
  • 300
  • 3
  • 14