1

My project structure looks like this.

build
  - folder where cmake outputs the solution file

client
  - client.c
  - CMakeLists.txt

server
  - server.c
  - CMakeLists.txt

open62541
  - open62541.c
  - open62541.h
  - CMakeLists.txt

CMakeLists.txt

The main CMakeLists.txt has the following code

cmake_minimum_required(VERSION 3.0)
project(openstack)
add_subdirectory(open62541)
add_subdirectory(server)

open62541/CMakeLists.txt has the following code

project(Lib1)
add_library(lib1 open62541.c open62541.h)

and server/CMakeLists.txt looks like this

   project(App)

   add_executable(app server.c)

   include_directories(${Lib1_SOURCE_DIR})

   target_link_libraries(app PRIVATE lib1 ws2_32 wsock32)

server.c has the following code.

#include "open62541.h"
#include "signal.h"
#include <stdlib.h>
#include "stdio.h"

static volatile UA_Boolean running = true;
static void stopHandler(int sig) {
    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
    running = false;
}

int main(void) {
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    UA_StatusCode retval = UA_Server_run(server, &running);

    UA_Server_delete(server);
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

server.c needs functions defined and declared in open62541.c and open62541.h.(I am not building the client project as of now)So, I have included open62541.h in the server.c file and in the server/CMakeLists.txt, I have given the link to the open62541 folder as you can see. I am getting the following linker errors in visual studio. The message is in german sorry for that.

    Erstellen gestartet...
1>------ Erstellen gestartet: Projekt: app, Konfiguration: Debug x64 ------
1>server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_UA_Server_delete" in Funktion "main".
1>server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_UA_Server_getConfig" in Funktion "main".
1>server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_UA_Server_run" in Funktion "main".
1>server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_UA_Server_new" in Funktion "main".
1>server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_UA_ServerConfig_setMinimalCustomBuffer" in Funktion "UA_ServerConfig_setMinimal".
1>server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_UA_Log_Stdout" in Funktion "stopHandler".
1>C:\Users\acer\CMake_Project\build\server\Debug\app.exe : fatal error LNK1120: 6 nicht aufgelöste Externe
1>Die Erstellung des Projekts "app.vcxproj" ist abgeschlossen -- FEHLER.
2>------ Erstellen übersprungen: Projekt: ALL_BUILD, Konfiguration: Debug x64 ------
2>Für diese Projektmappenkonfiguration wurde kein zu erstellendes Projekt ausgewählt. 
========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 2 aktuell, 1 übersprungen ==========

The project builds fine when I include server. c,open62541.c,open62541.h files in a single folder and use a single CMakeLists.txt file like this.

cmake_minimum_required(VERSION 3.0)

project(openstack)

set(SOURCES server.c open62541.c open62541.h)

add_executable(openstack ${SOURCES})

target_link_libraries(openstack PRIVATE ws2_32 wsock32)

However, I get errors when I try to structure my project in different folders. How can I solve these errors?

Gopala Krishna
  • 117
  • 1
  • 12
  • The prefix `__imp_` means that your executable expects the symbols to be defined in the **shared** library. But `add_library()` on Windows creates a **static** library by default. Most likely, the header `open62541.h` is "multi-purpose": it could be used when **build** the library as shared, it could be used when **link** the library as **static**, it could be used when **link** with the library as **shared**. The latter use case - linking with the shared library - is default one. The other use cases require specific macro definitions. – Tsyvarev Mar 28 '21 at 12:57
  • So I should add the library as shared library? How can I do that? – Gopala Krishna Mar 28 '21 at 16:13

1 Answers1

0

I've restructured your project a little to be more modern. See if this works and tell me what you get.

cmake_minimum_required(VERSION 3.15)
project(openstack LANGUAGES C)

add_subdirectory(open62541)
add_subdirectory(server)

# You didn't add_subdirectory client.
add_subdirectory(client)

open62541/CMakeLists.txt has the following code

add_library(lib1 STATIC)
target_sources(lib1 PRIVATE open62541.c open62541.h)
# Prefer to use public. To ease use of your library.
target_include_directores(lib1 PUBLIC ${CMAKE_CURRENT_LIST_DIR)

and server/CMakeLists.txt looks like this

add_executable(app)
target_sources(app PRIVATE server.c)
target_link_libraries(app PRIVATE lib1 ws2_32 wsock32)
  • Thanks for the answer. I got the same errors :( . Also in the main CMakeLists.txt, this line ´project(openstack LANGUAGES CXX)´ gives the error ´CMake cannot determine linker language for Target ´ , to make it work CXX should be replaced by C. – Gopala Krishna Mar 28 '21 at 16:08
  • I fixed the answer to use the C language my bad. Could you post your original CMakeLists.txt? Otherwise it's hard to figure out your problem. –  Mar 28 '21 at 18:14
  • I have already posted the original main CMakeLists.txt in the question. – Gopala Krishna Mar 28 '21 at 18:16
  • ? You said "The project builds fine when I include server. c,open62541.c,open62541.h files in a single folder and use a single CMakeLists.txt file" What does that file look like. –  Mar 28 '21 at 18:17
  • Make your library static see if that fixes it. –  Mar 28 '21 at 18:23