| 130 | |
| 131 | |
| 132 | unique_ptr<SharedLibrary> CompileCode(const std::vector<std::variant<filesystem::path, string>> &codes, const std::vector<string> &link_flags, bool keep_files, optional<string> compiler, optional<string> linker) |
| 133 | { |
| 134 | static ngstd::Timer tcompile("CompiledCF::Compile"); |
| 135 | static ngstd::Timer tlink("CompiledCF::Link"); |
| 136 | string object_files; |
| 137 | |
| 138 | filesystem::path cwd = filesystem::absolute("."); |
| 139 | filesystem::path lib_dir = CreateTempDir(); |
| 140 | string chdir_cmd = "cd " + lib_dir.string() + " && "; |
| 141 | |
| 142 | for(auto i : Range(codes.size())) { |
| 143 | filesystem::path src_file; |
| 144 | if(std::holds_alternative<filesystem::path>(codes[i])) |
| 145 | { |
| 146 | src_file = filesystem::absolute(std::get<filesystem::path>(codes[i])); |
| 147 | if(src_file.string().find(filesystem::temp_directory_path().string()) == 0) |
| 148 | { |
| 149 | // src_file is a temporary file outside lib_dir, copy it and use it's name for compilation |
| 150 | // to avoid ccache misses |
| 151 | auto dest_file = filesystem::path(lib_dir) / src_file.filename(); |
| 152 | filesystem::copy_file(src_file, dest_file, filesystem::copy_options::overwrite_existing); |
| 153 | src_file = dest_file.filename(); |
| 154 | } |
| 155 | } |
| 156 | else |
| 157 | { |
| 158 | string code = std::get<string>(codes[i]); |
| 159 | src_file = filesystem::path(lib_dir).append("code_" + ToString(i) + ".cpp"); |
| 160 | ofstream codefile(src_file); |
| 161 | codefile << code; |
| 162 | codefile.close(); |
| 163 | src_file = src_file.filename(); |
| 164 | } |
| 165 | cout << IM(3) << "compiling..." << endl; |
| 166 | tcompile.Start(); |
| 167 | #ifdef WIN32 |
| 168 | string compiler_cmd = compiler.value_or("ngscxx.bat"); |
| 169 | string scompile = "cmd /C \"ngscxx.bat " + src_file.string(); |
| 170 | object_files += " " + filesystem::path(src_file).replace_extension(".obj ").string(); |
| 171 | #else // WIN32 |
| 172 | string compiler_cmd = compiler.value_or("ngscxx"); |
| 173 | auto obj_file = " " + filesystem::path(src_file).replace_extension(".o").string(); |
| 174 | string scompile = compiler_cmd + " -c " + src_file.string() + " -o " + obj_file; |
| 175 | object_files += obj_file; |
| 176 | #endif // WIN32 |
| 177 | int err = system((chdir_cmd + scompile).c_str()); |
| 178 | if (err) throw Exception ("problem calling compiler, command: " + scompile); |
| 179 | tcompile.Stop(); |
| 180 | } |
| 181 | |
| 182 | cout << IM(3) << "linking..." << endl; |
| 183 | tlink.Start(); |
| 184 | auto lib_file = filesystem::path(lib_dir).append("library"); |
| 185 | #ifdef WIN32 |
| 186 | string linker_cmd = linker.value_or("ngsld.bat"); |
| 187 | lib_file.concat(".dll"); |
| 188 | string slink = "cmd /C \"" + linker_cmd + " /OUT:" + lib_file.string() + " " + object_files; |
| 189 | for (auto flag : link_flags) |
no test coverage detected