update: the fix is shown in the code.
I have a function defined in main.cpp
. I want to call it inside module Hello.
The file Hello.cppm
exports module Hello
with the implementation in hello.cpp
. The files are cut and pasted from larger files so compilation errors may occur. They should be close. (Compiler Explorer IDE wouldn't do modules for me.)
The question is, where can I put the extern declaration in hello.cpp
or maybe (it doesn't seem likely) Hello.cppm
? I've tried positions before and after the various module
statements. Most generate compiler errors. Where it is now, it compiles but won't link. I suspect it is considered a non-exported module Hello
function.
It should work in a header file, but can it work without a header file? This a learning experiment. In a header, everything works, but it shouldn't be necessary for a single function.
Using GCC 14.2 and CMake 2.38.2 on Ubuntu 24.04
The linker error.
function `main':
main.cpp:(.text.startup+0x1c): undefined reference to `mod::HelloAgain@Hello::operator()() const'
/usr/bin/ld: libHello.a(hello.cpp.o): in function `mod::Hello@Hello::operator()() const':
hello.cpp:(.text+0x1d): undefined reference to `hello_func_global@Hello[abi:cxx11]()'
main.cpp
#include <iostream>
#include <string>
using namespace std::literals;
auto hello_func_global() -> std::string {
return "Hello from a global function."s;
}
import Hello;
auto main() -> int {
mod::Hello();
constexpr mod::Hello hello;
constexpr mod::HelloAgain hello_again;
hello_again();
std::cout << hello_func() << '\n';
return 0;
}
Hello.cppm
module ;
#include <string>
export module Hello;
export namespace mod {
struct Hello {
auto operator()() const -> void;
};
}
hell0.cpp
module Hello;
extern auto hello_func_global() -> std::string; // <=== the fix
using namespace std::literals;
namespace mod {
auto Hello::operator()() const -> void {
hello_func_global();
std::cout << "Hello modules" << '\n';
}
}
The CMake file that builds the module.
cmake_minimum_required(VERSION 3.28.3)
project(Hello)
add_library(Hello)
target_sources(Hello
PUBLIC
FILE_SET CXX_MODULES
FILES Hello.cppm
PRIVATE
hello.cpp
hello_again.cpp
)
set_target_properties(Hello PROPERTIES CXX_MODULE_TYPE GLOBAL)
update: the fix is shown in the code.
I have a function defined in main.cpp
. I want to call it inside module Hello.
The file Hello.cppm
exports module Hello
with the implementation in hello.cpp
. The files are cut and pasted from larger files so compilation errors may occur. They should be close. (Compiler Explorer IDE wouldn't do modules for me.)
The question is, where can I put the extern declaration in hello.cpp
or maybe (it doesn't seem likely) Hello.cppm
? I've tried positions before and after the various module
statements. Most generate compiler errors. Where it is now, it compiles but won't link. I suspect it is considered a non-exported module Hello
function.
It should work in a header file, but can it work without a header file? This a learning experiment. In a header, everything works, but it shouldn't be necessary for a single function.
Using GCC 14.2 and CMake 2.38.2 on Ubuntu 24.04
The linker error.
function `main':
main.cpp:(.text.startup+0x1c): undefined reference to `mod::HelloAgain@Hello::operator()() const'
/usr/bin/ld: libHello.a(hello.cpp.o): in function `mod::Hello@Hello::operator()() const':
hello.cpp:(.text+0x1d): undefined reference to `hello_func_global@Hello[abi:cxx11]()'
main.cpp
#include <iostream>
#include <string>
using namespace std::literals;
auto hello_func_global() -> std::string {
return "Hello from a global function."s;
}
import Hello;
auto main() -> int {
mod::Hello();
constexpr mod::Hello hello;
constexpr mod::HelloAgain hello_again;
hello_again();
std::cout << hello_func() << '\n';
return 0;
}
Hello.cppm
module ;
#include <string>
export module Hello;
export namespace mod {
struct Hello {
auto operator()() const -> void;
};
}
hell0.cpp
module Hello;
extern auto hello_func_global() -> std::string; // <=== the fix
using namespace std::literals;
namespace mod {
auto Hello::operator()() const -> void {
hello_func_global();
std::cout << "Hello modules" << '\n';
}
}
The CMake file that builds the module.
cmake_minimum_required(VERSION 3.28.3)
project(Hello)
add_library(Hello)
target_sources(Hello
PUBLIC
FILE_SET CXX_MODULES
FILES Hello.cppm
PRIVATE
hello.cpp
hello_again.cpp
)
set_target_properties(Hello PROPERTIES CXX_MODULE_TYPE GLOBAL)
Share
Improve this question
edited Feb 7 at 18:47
Rud48
asked Feb 6 at 22:33
Rud48Rud48
9234 silver badges16 bronze badges
6
|
Show 1 more comment
1 Answer
Reset to default 6I suspect it is considered a non-exported
module Hello
function.
Exactly.
The question is, where can I put the extern declaration in
hello.cpp
or maybe (it doesn't seem likely)Hello.cppm
?
You don't have any choice but to put it after module Hello;
.
To tell the compiler that it is not attached to the module, use a linkage-specification extern "C++"
.
extern "C++" auto hello_func_global() -> std::string;
hell0.cpp
added to the build? – StoryTeller - Unslander Monica Commented Feb 6 at 23:10